1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Demangler for g++ V3 ABI.
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Free Software Foundation, Inc.
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Written by Ian Lance Taylor <ian@wasabisystems.com>.
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of the libiberty library, which is part of GCC.
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is free software; you can redistribute it and/or modify
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   it under the terms of the GNU General Public License as published by
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the Free Software Foundation; either version 2 of the License, or
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (at your option) any later version.
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   In addition to the permissions in the GNU General Public License, the
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Free Software Foundation gives you unlimited permission to link the
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   compiled version of this file into combinations with other programs,
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and to distribute those combinations without any restriction coming
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   from the use of this file.  (The General Public License restrictions
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do apply in other respects; for example, they cover modification of
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the file, and distribution when not linked into a combined
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   executable.)
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful,
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   but WITHOUT ANY WARRANTY; without even the implied warranty of
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GNU General Public License for more details.
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This code implements a demangler for the g++ V3 ABI.  The ABI is
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   described on this web page:
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       http://www.codesourcery.com/cxx-abi/abi.html#mangling
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This code was written while looking at the demangler written by
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Alex Samuel <samuel@codesourcery.com>.
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This code first pulls the mangled name apart into a list of
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   components, and then walks the list generating the demangled
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name.
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file will normally define the following functions, q.v.:
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      char *cplus_demangle_v3(const char *mangled, int options)
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      char *java_demangle_v3(const char *mangled)
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int cplus_demangle_v3_callback(const char *mangled, int options,
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     demangle_callbackref callback)
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int java_demangle_v3_callback(const char *mangled,
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    demangle_callbackref callback)
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      enum gnu_v3_ctor_kinds is_gnu_v3_mangled_ctor (const char *name)
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      enum gnu_v3_dtor_kinds is_gnu_v3_mangled_dtor (const char *name)
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Also, the interface to the component list is public, and defined in
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   demangle.h.  The interface consists of these types, which are
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   defined in demangle.h:
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      enum demangle_component_type
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      demangle_callbackref
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and these functions defined in this file:
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cplus_demangle_fill_name
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cplus_demangle_fill_extended_operator
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cplus_demangle_fill_ctor
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cplus_demangle_fill_dtor
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cplus_demangle_print
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cplus_demangle_print_callback
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and other functions defined in the file cp-demint.c.
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file also defines some other functions and variables which are
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   only to be used by the file cp-demint.c.
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Preprocessor macros you can define while compiling this file:
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IN_LIBGCC2
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      If defined, this file defines the following functions, q.v.:
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         char *__cxa_demangle (const char *mangled, char *buf, size_t *len,
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               int *status)
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         int __gcclibcxx_demangle_callback (const char *,
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                            void (*)
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                              (const char *, size_t, void *),
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                            void *)
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      instead of cplus_demangle_v3[_callback]() and
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      java_demangle_v3[_callback]().
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IN_GLIBCPP_V3
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      If defined, this file defines only __cxa_demangle() and
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __gcclibcxx_demangle_callback(), and no other publically visible
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      functions or variables.
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   STANDALONE_DEMANGLER
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      If defined, this file defines a main() function which demangles
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      any arguments, or, if none, demangles stdin.
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CP_DEMANGLE_DEBUG
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      If defined, turns on debugging mode, which prints information on
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      stdout about the mangled string.  This is not generally useful.
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined (_AIX) && !defined (__GNUC__)
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown #pragma alloca
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_CONFIG_H
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "config.h"
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_STDLIB_H
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_STRING_H
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <string.h>
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_ALLOCA_H
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# include <alloca.h>
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# ifndef alloca
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  ifdef __GNUC__
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   define alloca __builtin_alloca
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  else
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern char *alloca ();
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  endif /* __GNUC__ */
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif /* alloca */
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* HAVE_ALLOCA_H */
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "ansidecl.h"
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libiberty.h"
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "vg_libciface.h"
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "demangle.h"
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "cp-demangle.h"
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* If IN_GLIBCPP_V3 is defined, some functions are made static.  We
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   also rename them via #define to avoid compiler errors when the
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static definition conflicts with the extern declaration in a header
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   file.  */
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef IN_GLIBCPP_V3
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CP_STATIC_IF_GLIBCPP_V3 static
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define cplus_demangle_fill_name d_fill_name
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int d_fill_name (struct demangle_component *, const char *, int);
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define cplus_demangle_fill_extended_operator d_fill_extended_operator
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_fill_extended_operator (struct demangle_component *, int,
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct demangle_component *);
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define cplus_demangle_fill_ctor d_fill_ctor
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_fill_ctor (struct demangle_component *, enum gnu_v3_ctor_kinds,
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *);
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define cplus_demangle_fill_dtor d_fill_dtor
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_fill_dtor (struct demangle_component *, enum gnu_v3_dtor_kinds,
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *);
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define cplus_demangle_mangled_name d_mangled_name
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_mangled_name (struct d_info *, int);
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define cplus_demangle_type d_type
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_type (struct d_info *);
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define cplus_demangle_print d_print
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic char *d_print (int, const struct demangle_component *, int, size_t *);
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define cplus_demangle_print_callback d_print_callback
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int d_print_callback (int, const struct demangle_component *,
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             demangle_callbackref, void *);
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define cplus_demangle_init_info d_init_info
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void d_init_info (const char *, int, size_t, struct d_info *);
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else /* ! defined(IN_GLIBCPP_V3) */
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CP_STATIC_IF_GLIBCPP_V3
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! defined(IN_GLIBCPP_V3) */
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* See if the compiler supports dynamic arrays.  */
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef __GNUC__
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CP_DYNAMIC_ARRAYS
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef __STDC__
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef __STDC_VERSION__
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if __STDC_VERSION__ >= 199901L
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CP_DYNAMIC_ARRAYS
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* __STDC__VERSION >= 199901L */
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* defined (__STDC_VERSION__) */
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* defined (__STDC__) */
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! defined (__GNUC__) */
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* We avoid pulling in the ctype tables, to prevent pulling in
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   additional unresolved symbols when this code is used in a library.
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   FIXME: Is this really a valid reason?  This comes from the original
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   V3 demangler code.
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   As of this writing this file has the following undefined references
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   when compiled with -DIN_GLIBCPP_V3: realloc, free, memcpy, strcpy,
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   strcat, strlen.  */
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The prefix prepended by GCC to an identifier represnting the
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   anonymous namespace.  */
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ANONYMOUS_NAMESPACE_PREFIX_LEN \
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  (sizeof (ANONYMOUS_NAMESPACE_PREFIX) - 1)
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Information we keep for the standard substitutions.  */
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct d_standard_sub_info
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The code for this substitution.  */
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char code;
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The simple string it expands to.  */
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *simple_expansion;
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The length of the simple expansion.  */
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int simple_len;
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The results of a full, verbose, expansion.  This is used when
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     qualifying a constructor/destructor, or when in verbose mode.  */
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *full_expansion;
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The length of the full expansion.  */
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int full_len;
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* What to set the last_name field of d_info to; NULL if we should
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     not set it.  This is only relevant when qualifying a
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     constructor/destructor.  */
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *set_last_name;
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The length of set_last_name.  */
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int set_last_name_len;
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Accessors for subtrees of struct demangle_component.  */
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define d_left(dc) ((dc)->u.s_binary.left)
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define d_right(dc) ((dc)->u.s_binary.right)
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A list of templates.  This is used while printing.  */
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct d_print_template
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Next template on the list.  */
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_template *next;
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* This template.  */
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const struct demangle_component *template_decl;
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A list of type modifiers.  This is used while printing.  */
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct d_print_mod
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Next modifier on the list.  These are in the reverse of the order
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     in which they appeared in the mangled string.  */
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_mod *next;
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The modifier.  */
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const struct demangle_component *mod;
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Whether this modifier was printed.  */
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int printed;
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The list of templates which applies to this modifier.  */
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_template *templates;
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* We use these structures to hold information during printing.  */
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct d_growable_string
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Buffer holding the result.  */
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char *buf;
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Current length of data in buffer.  */
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t len;
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Allocated size of buffer.  */
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t alc;
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Set to 1 if we had a memory allocation failure.  */
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int allocation_failure;
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownenum { D_PRINT_BUFFER_LENGTH = 256 };
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct d_print_info
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The options passed to the demangler.  */
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int options;
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Fixed-length allocated buffer for demangled data, flushed to the
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     callback with a NUL termination once full.  */
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char buf[D_PRINT_BUFFER_LENGTH];
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Current length of data in buffer.  */
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t len;
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The last character printed, saved individually so that it survives
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     any buffer flush.  */
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char last_char;
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Callback function to handle demangled buffer flush.  */
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  demangle_callbackref callback;
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Opaque callback argument.  */
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  void *opaque;
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The current list of templates, if any.  */
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_template *templates;
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The current list of modifiers (e.g., pointer, reference, etc.),
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     if any.  */
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_mod *modifiers;
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Set to 1 if we saw a demangling error.  */
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int demangle_failure;
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The current index into any template argument packs we are using
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     for printing.  */
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int pack_index;
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef CP_DEMANGLE_DEBUG
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void d_dump (struct demangle_component *, int);
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_empty (struct d_info *);
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_comp (struct d_info *, enum demangle_component_type,
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *,
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *);
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_name (struct d_info *, const char *, int);
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_builtin_type (struct d_info *,
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     const struct demangle_builtin_type_info *);
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_operator (struct d_info *,
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct demangle_operator_info *);
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_extended_operator (struct d_info *, int,
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct demangle_component *);
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_ctor (struct d_info *, enum gnu_v3_ctor_kinds,
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *);
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_dtor (struct d_info *, enum gnu_v3_dtor_kinds,
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *);
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_template_param (struct d_info *, long);
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_sub (struct d_info *, const char *, int);
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownhas_return_type (struct demangle_component *);
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_ctor_dtor_or_conversion (struct demangle_component *);
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_encoding (struct d_info *, int);
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_name (struct d_info *);
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_nested_name (struct d_info *);
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_prefix (struct d_info *);
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_unqualified_name (struct d_info *);
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_source_name (struct d_info *);
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic long d_number (struct d_info *);
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_identifier (struct d_info *, int);
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_operator_name (struct d_info *);
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_special_name (struct d_info *);
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int d_call_offset (struct d_info *, int);
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_ctor_dtor_name (struct d_info *);
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component **
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_cv_qualifiers (struct d_info *, struct demangle_component **, int);
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_function_type (struct d_info *);
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_bare_function_type (struct d_info *, int);
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_class_enum_type (struct d_info *);
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_array_type (struct d_info *);
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_pointer_to_member_type (struct d_info *);
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_param (struct d_info *);
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_template_args (struct d_info *);
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_arg (struct d_info *);
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_expression (struct d_info *);
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_expr_primary (struct d_info *);
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_local_name (struct d_info *);
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int d_discriminator (struct d_info *);
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_add_substitution (struct d_info *, struct demangle_component *);
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_substitution (struct d_info *, int);
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void d_growable_string_init (struct d_growable_string *, size_t);
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_resize (struct d_growable_string *, size_t);
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_append_buffer (struct d_growable_string *,
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 const char *, size_t);
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_callback_adapter (const char *, size_t, void *);
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_init (struct d_print_info *, int, demangle_callbackref, void *);
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_print_error (struct d_print_info *);
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline int d_print_saw_error (struct d_print_info *);
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_print_flush (struct d_print_info *);
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_append_char (struct d_print_info *, char);
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_append_buffer (struct d_print_info *,
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    const char *, size_t);
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_append_string (struct d_print_info *, const char *);
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline char d_last_char (struct d_print_info *);
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_comp (struct d_print_info *, const struct demangle_component *);
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_java_identifier (struct d_print_info *, const char *, int);
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_mod_list (struct d_print_info *, struct d_print_mod *, int);
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_mod (struct d_print_info *, const struct demangle_component *);
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_function_type (struct d_print_info *,
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       const struct demangle_component *,
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       struct d_print_mod *);
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_array_type (struct d_print_info *,
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    const struct demangle_component *,
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    struct d_print_mod *);
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_expr_op (struct d_print_info *, const struct demangle_component *);
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_cast (struct d_print_info *, const struct demangle_component *);
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int d_demangle_callback (const char *, int,
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                demangle_callbackref, void *);
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic char *d_demangle (const char *, int, size_t *);
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef CP_DEMANGLE_DEBUG
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_dump (struct demangle_component *dc, int indent)
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int i;
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (indent == 0)
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        printf ("failed demangling\n");
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (i = 0; i < indent; ++i)
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    putchar (' ');
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_NAME:
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("name '%.*s'\n", dc->u.s_name.len, dc->u.s_name.s);
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("template parameter %ld\n", dc->u.s_number.number);
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CTOR:
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("constructor %d\n", (int) dc->u.s_ctor.kind);
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_dump (dc->u.s_ctor.name, indent + 2);
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DTOR:
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("destructor %d\n", (int) dc->u.s_dtor.kind);
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_dump (dc->u.s_dtor.name, indent + 2);
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_SUB_STD:
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("standard substitution %s\n", dc->u.s_string.string);
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("builtin type %s\n", dc->u.s_builtin.type->name);
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_OPERATOR:
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("operator %s\n", dc->u.s_operator.op->name);
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("extended operator with %d args\n",
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dc->u.s_extended_operator.args);
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_dump (dc->u.s_extended_operator.name, indent + 2);
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_QUAL_NAME:
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("qualified name\n");
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LOCAL_NAME:
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("local name\n");
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPED_NAME:
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("typed name\n");
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE:
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("template\n");
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTABLE:
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("vtable\n");
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTT:
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("VTT\n");
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("construction vtable\n");
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO:
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("typeinfo\n");
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_NAME:
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("typeinfo name\n");
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_FN:
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("typeinfo function\n");
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_THUNK:
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("thunk\n");
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("virtual thunk\n");
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COVARIANT_THUNK:
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("covariant thunk\n");
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_CLASS:
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("java class\n");
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_GUARD:
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("guard\n");
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFTEMP:
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("reference temporary\n");
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("hidden alias\n");
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT:
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("restrict\n");
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE:
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("volatile\n");
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST:
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("const\n");
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("restrict this\n");
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("volatile this\n");
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("const this\n");
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("vendor type qualifier\n");
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_POINTER:
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("pointer\n");
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFERENCE:
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("reference\n");
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("rvalue reference\n");
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPLEX:
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("complex\n");
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_IMAGINARY:
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("imaginary\n");
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE:
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("vendor type\n");
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("function type\n");
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARRAY_TYPE:
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("array type\n");
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("pointer to member type\n");
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARGLIST:
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("argument list\n");
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("template argument list\n");
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CAST:
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("cast\n");
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_UNARY:
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("unary operator\n");
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY:
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("binary operator\n");
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY_ARGS:
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("binary operator arguments\n");
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY:
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("trinary operator\n");
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG1:
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("trinary operator arguments 1\n");
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG2:
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("trinary operator arguments 1\n");
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL:
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("literal\n");
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL_NEG:
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("negative literal\n");
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_RESOURCE:
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("java resource\n");
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPOUND_NAME:
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("compound name\n");
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CHARACTER:
679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("character '%c'\n",  dc->u.s_character.character);
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DECLTYPE:
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("decltype\n");
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PACK_EXPANSION:
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("pack expansion\n");
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_dump (d_left (dc), indent + 2);
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_dump (d_right (dc), indent + 2);
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* CP_DEMANGLE_DEBUG */
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Fill in a DEMANGLE_COMPONENT_NAME.  */
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_fill_name (struct demangle_component *p, const char *s, int len)
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p == NULL || s == NULL || len == 0)
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->type = DEMANGLE_COMPONENT_NAME;
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_name.s = s;
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_name.len = len;
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR.  */
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_fill_extended_operator (struct demangle_component *p, int args,
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                       struct demangle_component *name)
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p == NULL || args < 0 || name == NULL)
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_extended_operator.args = args;
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_extended_operator.name = name;
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Fill in a DEMANGLE_COMPONENT_CTOR.  */
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_fill_ctor (struct demangle_component *p,
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          enum gnu_v3_ctor_kinds kind,
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct demangle_component *name)
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p == NULL
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      || name == NULL
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      || (kind < gnu_v3_complete_object_ctor
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && kind > gnu_v3_complete_object_allocating_ctor))
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->type = DEMANGLE_COMPONENT_CTOR;
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_ctor.kind = kind;
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_ctor.name = name;
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Fill in a DEMANGLE_COMPONENT_DTOR.  */
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_fill_dtor (struct demangle_component *p,
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          enum gnu_v3_dtor_kinds kind,
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct demangle_component *name)
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p == NULL
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      || name == NULL
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      || (kind < gnu_v3_deleting_dtor
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && kind > gnu_v3_base_object_dtor))
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->type = DEMANGLE_COMPONENT_DTOR;
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_dtor.kind = kind;
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_dtor.name = name;
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new component.  */
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_empty (struct d_info *di)
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (di->next_comp >= di->num_comps)
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = &di->comps[di->next_comp];
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ++di->next_comp;
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new generic component.  */
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_comp (struct d_info *di, enum demangle_component_type type,
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *left,
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *right)
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* We check for errors here.  A typical error would be a NULL return
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     from a subroutine.  We catch those here, and return NULL
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     upward.  */
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (type)
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These types require two parameters.  */
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_QUAL_NAME:
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LOCAL_NAME:
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPED_NAME:
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE:
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_UNARY:
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY:
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY_ARGS:
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY:
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG1:
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG2:
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL:
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL_NEG:
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPOUND_NAME:
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (left == NULL || right == NULL)
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These types only require one parameter.  */
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTABLE:
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTT:
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO:
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_NAME:
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_FN:
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_THUNK:
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COVARIANT_THUNK:
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_CLASS:
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_GUARD:
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFTEMP:
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_POINTER:
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFERENCE:
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPLEX:
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_IMAGINARY:
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE:
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CAST:
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_RESOURCE:
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DECLTYPE:
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PACK_EXPANSION:
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (left == NULL)
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* This needs a right parameter, but the left parameter can be
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 empty.  */
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARRAY_TYPE:
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (right == NULL)
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These are allowed to have no parameters--in some cases they
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 will be filled in later.  */
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT:
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE:
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST:
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARGLIST:
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Other types should not be seen here.  */
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = type;
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_binary.left = left;
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_binary.right = right;
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new name component.  */
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_name (struct d_info *di, const char *s, int len)
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_fill_name (p, s, len))
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new builtin type component.  */
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_builtin_type (struct d_info *di,
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     const struct demangle_builtin_type_info *type)
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (type == NULL)
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE;
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_builtin.type = type;
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new operator component.  */
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_operator (struct d_info *di, const struct demangle_operator_info *op)
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_OPERATOR;
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_operator.op = op;
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new extended operator component.  */
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_extended_operator (struct d_info *di, int args,
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct demangle_component *name)
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_fill_extended_operator (p, args, name))
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new constructor component.  */
936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_ctor (struct d_info *di, enum gnu_v3_ctor_kinds kind,
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *name)
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_fill_ctor (p, kind, name))
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new destructor component.  */
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_dtor (struct d_info *di, enum gnu_v3_dtor_kinds kind,
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *name)
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_fill_dtor (p, kind, name))
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new template parameter.  */
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_template_param (struct d_info *di, long i)
967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_TEMPLATE_PARAM;
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_number.number = i;
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new standard substitution component.  */
980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_sub (struct d_info *di, const char *name, int len)
983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_SUB_STD;
990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_string.string = name;
991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_string.len = len;
992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <mangled-name> ::= _Z <encoding>
997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TOP_LEVEL is non-zero when called at the top level.  */
999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct demangle_component *
1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_mangled_name (struct d_info *di, int top_level)
1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, '_'))
1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'Z'))
1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_encoding (di, top_level);
1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return whether a function should have a return type.  The argument
1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   is the function name, which may be qualified in various ways.  The
1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   rules are that template functions have return types with some
1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   exceptions, function types which are not part of a function name
1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mangling have return types with some exceptions, and non-template
1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   function names do not have return types.  The exceptions are that
1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   constructors, destructors, and conversion operators do not have
1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return types.  */
1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownhas_return_type (struct demangle_component *dc)
1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 0;
1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE:
1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ! is_ctor_dtor_or_conversion (d_left (dc));
1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return has_return_type (d_left (dc));
1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return whether a name is a constructor, a destructor, or a
1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   conversion operator.  */
1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_ctor_dtor_or_conversion (struct demangle_component *dc)
1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 0;
1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_QUAL_NAME:
1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LOCAL_NAME:
1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return is_ctor_dtor_or_conversion (d_right (dc));
1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CTOR:
1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DTOR:
1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CAST:
1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 1;
1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <encoding> ::= <(function) name> <bare-function-type>
1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              ::= <(data) name>
1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              ::= <special-name>
1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TOP_LEVEL is non-zero when called at the top level, in which case
1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if DMGL_PARAMS is not set we do not demangle the function
1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parameters.  We only set this at the top level, because otherwise
1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   we would not correctly demangle names in local scopes.  */
1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_encoding (struct d_info *di, int top_level)
1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek = d_peek_char (di);
1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == 'G' || peek == 'T')
1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_special_name (di);
1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *dc;
1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = d_name (di);
1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dc != NULL && top_level && (di->options & DMGL_PARAMS) == 0)
1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* Strip off any initial CV-qualifiers, as they really apply
1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     to the `this' parameter, and they were not output by the
1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     v2 demangler without DMGL_PARAMS.  */
1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		 || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		 || dc->type == DEMANGLE_COMPONENT_CONST_THIS)
1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_left (dc);
1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then
1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     there may be CV-qualifiers on its right argument which
1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     really apply here; this happens when parsing a class
1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     which is local to a function.  */
1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      struct demangle_component *dcr;
1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dcr = d_right (dc);
1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS
1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		     || dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS
1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		     || dcr->type == DEMANGLE_COMPONENT_CONST_THIS)
1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dcr = d_left (dcr);
1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dc->u.s_binary.right = dcr;
1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return dc;
1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dc == NULL || peek == '\0' || peek == 'E')
1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return dc;
1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc,
1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			  d_bare_function_type (di, has_return_type (dc)));
1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <name> ::= <nested-name>
1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <unscoped-name>
1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <unscoped-template-name> <template-args>
1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <local-name>
1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <unscoped-name> ::= <unqualified-name>
1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   ::= St <unqualified-name>
1126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <unscoped-template-name> ::= <unscoped-name>
1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            ::= <substitution>
1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_name (struct d_info *di)
1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek = d_peek_char (di);
1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *dc;
1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (peek)
1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'N':
1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_nested_name (di);
1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'Z':
1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_local_name (di);
1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'L':
1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_unqualified_name (di);
1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'S':
1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int subst;
1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (d_peek_next_char (di) != 't')
1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_substitution (di, 0);
1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    subst = 1;
1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	else
1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_advance (di, 2);
1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME,
1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_make_name (di, "std", 3),
1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_unqualified_name (di));
1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    di->expansion += 3;
1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    subst = 0;
1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (d_peek_char (di) != 'I')
1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* The grammar does not permit this case to occur if we
1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       called d_substitution() above (i.e., subst == 1).  We
1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       don't bother to check.  */
1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	else
1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* This is <template-args>, which means that we just saw
1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       <unscoped-template-name>, which is a substitution
1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       candidate if we didn't just get it from a
1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       substitution.  */
1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! subst)
1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (! d_add_substitution (di, dc))
1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  return NULL;
1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_template_args (di));
1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return dc;
1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = d_unqualified_name (di);
1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'I')
1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* This is <template-args>, which means that we just saw
1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     <unscoped-template-name>, which is a substitution
1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     candidate.  */
1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_add_substitution (di, dc))
1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    d_template_args (di));
1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return dc;
1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_nested_name (struct d_info *di)
1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **pret;
1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'N'))
1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pret = d_cv_qualifiers (di, &ret, 1);
1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (pret == NULL)
1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *pret = d_prefix (di);
1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (*pret == NULL)
1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'E'))
1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <prefix> ::= <prefix> <unqualified-name>
1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ::= <template-prefix> <template-args>
1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ::= <template-param>
1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ::=
1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ::= <substitution>
1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <template-prefix> ::= <prefix> <(template) unqualified-name>
1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ::= <template-param>
1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ::= <substitution>
1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_prefix (struct d_info *di)
1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret = NULL;
1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      char peek;
1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      enum demangle_component_type comb_type;
1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *dc;
1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (peek == '\0')
1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* The older code accepts a <local-name> here, but I don't see
1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 that in the grammar.  The older code does not accept a
1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 <template-param> here.  */
1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      comb_type = DEMANGLE_COMPONENT_QUAL_NAME;
1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (IS_DIGIT (peek)
1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  || IS_LOWER (peek)
1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  || peek == 'C'
1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  || peek == 'D'
1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  || peek == 'L')
1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_unqualified_name (di);
1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'S')
1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_substitution (di, 1);
1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'I')
1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (ret == NULL)
1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  comb_type = DEMANGLE_COMPONENT_TEMPLATE;
1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  dc = d_template_args (di);
1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'T')
1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_template_param (di);
1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'E')
1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return ret;
1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ret == NULL)
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret = dc;
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret = d_make_comp (di, comb_type, ret, dc);
1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (peek != 'S' && d_peek_char (di) != 'E')
1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_add_substitution (di, ret))
1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <unqualified-name> ::= <operator-name>
1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      ::= <ctor-dtor-name>
1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      ::= <source-name>
1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      ::= <local-source-name>
1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    <local-source-name>	::= L <source-name> <discriminator>
1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_unqualified_name (struct d_info *di)
1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (IS_DIGIT (peek))
1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_source_name (di);
1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (IS_LOWER (peek))
1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *ret;
1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_operator_name (di);
1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion += sizeof "operator" + ret->u.s_operator.op->len - 2;
1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ret;
1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (peek == 'C' || peek == 'D')
1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_ctor_dtor_name (di);
1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (peek == 'L')
1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component * ret;
1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_source_name (di);
1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ret == NULL)
1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_discriminator (di))
1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ret;
1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <source-name> ::= <(positive length) number> <identifier>  */
1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_source_name (struct d_info *di)
1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long len;
1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  len = d_number (di);
1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (len <= 0)
1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ret = d_identifier (di, len);
1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->last_name = ret;
1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* number ::= [n] <(non-negative decimal integer)>  */
1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic long
1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_number (struct d_info *di)
1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int negative;
1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long ret;
1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  negative = 0;
1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == 'n')
1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      negative = 1;
1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ret = 0;
1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! IS_DIGIT (peek))
1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (negative)
1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = - ret;
1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return ret;
1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = ret * 10 + peek - '0';
1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* identifier ::= <(unqualified source code identifier)>  */
1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_identifier (struct d_info *di, int len)
1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *name;
1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  name = d_str (di);
1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (di->send - name < len)
1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_advance (di, len);
1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* A Java mangled name may have a trailing '$' if it is a C++
1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     keyword.  This '$' is not included in the length count.  We just
1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     ignore the '$'.  */
1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if ((di->options & DMGL_JAVA) != 0
1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      && d_peek_char (di) == '$')
1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_advance (di, 1);
1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Look for something which looks like a gcc encoding of an
1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     anonymous namespace, and replace it with a more user friendly
1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     name.  */
1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2
1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      && memcmp (name, ANONYMOUS_NAMESPACE_PREFIX,
1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		 ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0)
1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const char *s;
1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      s = name + ANONYMOUS_NAMESPACE_PREFIX_LEN;
1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((*s == '.' || *s == '_' || *s == '$')
1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && s[1] == 'N')
1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion -= len - sizeof "(anonymous namespace)";
1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_name (di, "(anonymous namespace)",
1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      sizeof "(anonymous namespace)" - 1);
1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_make_name (di, name, len);
1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* operator_name ::= many different two character encodings.
1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 ::= cv <type>
1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 ::= v <digit> <source-name>
1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define NL(s) s, (sizeof s) - 1
1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst struct demangle_operator_info cplus_demangle_operators[] =
1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "aN", NL ("&="),        2 },
1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "aS", NL ("="),         2 },
1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "aa", NL ("&&"),        2 },
1449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ad", NL ("&"),         1 },
1450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "an", NL ("&"),         2 },
1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "cl", NL ("()"),        2 },
1452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "cm", NL (","),         2 },
1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "co", NL ("~"),         1 },
1454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "dV", NL ("/="),        2 },
1455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "da", NL ("delete[]"),  1 },
1456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "de", NL ("*"),         1 },
1457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "dl", NL ("delete"),    1 },
1458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "dt", NL ("."),         2 },
1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "dv", NL ("/"),         2 },
1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "eO", NL ("^="),        2 },
1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "eo", NL ("^"),         2 },
1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "eq", NL ("=="),        2 },
1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ge", NL (">="),        2 },
1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "gt", NL (">"),         2 },
1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ix", NL ("[]"),        2 },
1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "lS", NL ("<<="),       2 },
1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "le", NL ("<="),        2 },
1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ls", NL ("<<"),        2 },
1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "lt", NL ("<"),         2 },
1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "mI", NL ("-="),        2 },
1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "mL", NL ("*="),        2 },
1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "mi", NL ("-"),         2 },
1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ml", NL ("*"),         2 },
1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "mm", NL ("--"),        1 },
1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "na", NL ("new[]"),     1 },
1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ne", NL ("!="),        2 },
1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ng", NL ("-"),         1 },
1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "nt", NL ("!"),         1 },
1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "nw", NL ("new"),       1 },
1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "oR", NL ("|="),        2 },
1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "oo", NL ("||"),        2 },
1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "or", NL ("|"),         2 },
1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pL", NL ("+="),        2 },
1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pl", NL ("+"),         2 },
1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pm", NL ("->*"),       2 },
1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pp", NL ("++"),        1 },
1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ps", NL ("+"),         1 },
1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pt", NL ("->"),        2 },
1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "qu", NL ("?"),         3 },
1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "rM", NL ("%="),        2 },
1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "rS", NL (">>="),       2 },
1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "rm", NL ("%"),         2 },
1493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "rs", NL (">>"),        2 },
1494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "st", NL ("sizeof "),   1 },
1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "sz", NL ("sizeof "),   1 },
1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { NULL, NULL, 0,          0 }
1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_operator_name (struct d_info *di)
1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char c1;
1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char c2;
1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  c1 = d_next_char (di);
1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  c2 = d_next_char (di);
1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (c1 == 'v' && IS_DIGIT (c2))
1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_make_extended_operator (di, c2 - '0', d_source_name (di));
1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (c1 == 'c' && c2 == 'v')
1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_make_comp (di, DEMANGLE_COMPONENT_CAST,
1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			cplus_demangle_type (di), NULL);
1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* LOW is the inclusive lower bound.  */
1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int low = 0;
1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* HIGH is the exclusive upper bound.  We subtract one to ignore
1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 the sentinel at the end of the array.  */
1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int high = ((sizeof (cplus_demangle_operators)
1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   / sizeof (cplus_demangle_operators[0]))
1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  - 1);
1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (1)
1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  int i;
1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  const struct demangle_operator_info *p;
1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  i = low + (high - low) / 2;
1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  p = cplus_demangle_operators + i;
1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (c1 == p->code[0] && c2 == p->code[1])
1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return d_make_operator (di, p);
1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (c1 < p->code[0] || (c1 == p->code[0] && c2 < p->code[1]))
1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    high = i;
1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  else
1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    low = i + 1;
1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (low == high)
1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_character (struct d_info *di, int c)
1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_CHARACTER;
1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_character.character = c;
1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_java_resource (struct d_info *di)
1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p = NULL;
1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *next = NULL;
1561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long len, i;
1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char c;
1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *str;
1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  len = d_number (di);
1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (len <= 1)
1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Eat the leading '_'.  */
1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_next_char (di) != '_')
1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  len--;
1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  str = d_str (di);
1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  i = 0;
1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (len > 0)
1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      c = str[i];
1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!c)
1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Each chunk is either a '$' escape...  */
1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (c == '$')
1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  i++;
1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  switch (str[i++])
1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    case 'S':
1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = '/';
1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      break;
1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    case '_':
1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = '.';
1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      break;
1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    case '$':
1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = '$';
1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      break;
1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    default:
1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return NULL;
1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  next = d_make_character (di, c);
1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, i);
1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  str = d_str (di);
1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  len -= i;
1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  i = 0;
1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (next == NULL)
1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... or a sequence of characters.  */
1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  while (i < len && str[i] && str[i] != '$')
1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    i++;
1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  next = d_make_name (di, str, i);
1616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, i);
1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  str = d_str (di);
1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  len -= i;
1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  i = 0;
1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (next == NULL)
1621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (p == NULL)
1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	p = next;
1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  p = d_make_comp (di, DEMANGLE_COMPONENT_COMPOUND_NAME, p, next);
1629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (p == NULL)
1630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_comp (di, DEMANGLE_COMPONENT_JAVA_RESOURCE, p, NULL);
1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <special-name> ::= TV <type>
1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TT <type>
1641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TI <type>
1642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TS <type>
1643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= GV <(object) name>
1644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= T <call-offset> <(base) encoding>
1645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Tc <call-offset> <call-offset> <(base) encoding>
1646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Also g++ extensions:
1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TC <type> <(offset) number> _ <(base) type>
1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TF <type>
1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TJ <type>
1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= GR <name>
1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  ::= GA <encoding>
1652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  ::= Gr <resource name>
1653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_special_name (struct d_info *di)
1657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->expansion += 20;
1659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_check_char (di, 'T'))
1660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (d_next_char (di))
1662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'V':
1664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion -= 5;
1665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_VTABLE,
1666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'T':
1668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion -= 10;
1669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_VTT,
1670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'I':
1672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO,
1673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'S':
1675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_NAME,
1676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'h':
1679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_call_offset (di, 'h'))
1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_THUNK,
1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_encoding (di, 0), NULL);
1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'v':
1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_call_offset (di, 'v'))
1686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_VIRTUAL_THUNK,
1688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_encoding (di, 0), NULL);
1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'c':
1691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_call_offset (di, '\0'))
1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_call_offset (di, '\0'))
1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_COVARIANT_THUNK,
1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_encoding (di, 0), NULL);
1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'C':
1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *derived_type;
1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    long offset;
1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *base_type;
1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    derived_type = cplus_demangle_type (di);
1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    offset = d_number (di);
1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (offset < 0)
1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return NULL;
1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! d_check_char (di, '_'))
1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return NULL;
1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    base_type = cplus_demangle_type (di);
1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* We don't display the offset.  FIXME: We should display
1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       it in verbose mode.  */
1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    di->expansion += 5;
1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return d_make_comp (di, DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				base_type, derived_type);
1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'F':
1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_FN,
1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'J':
1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_JAVA_CLASS,
1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return NULL;
1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (d_check_char (di, 'G'))
1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (d_next_char (di))
1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'V':
1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, d_name (di), NULL);
1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'R':
1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, d_name (di),
1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      NULL);
1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'A':
1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_HIDDEN_ALIAS,
1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_encoding (di, 0), NULL);
1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'r':
1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_java_resource (di);
1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return NULL;
1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <call-offset> ::= h <nv-offset> _
1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 ::= v <v-offset> _
1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <nv-offset> ::= <(offset) number>
1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <v-offset> ::= <(offset) number> _ <(virtual offset) number>
1761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The C parameter, if not '\0', is a character we just read which is
1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the start of the <call-offset>.
1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   We don't display the offset information anywhere.  FIXME: We should
1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   display it in verbose mode.  */
1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_call_offset (struct d_info *di, int c)
1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (c == '\0')
1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    c = d_next_char (di);
1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (c == 'h')
1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_number (di);
1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (c == 'v')
1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_number (di);
1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_check_char (di, '_'))
1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return 0;
1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_number (di);
1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, '_'))
1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <ctor-dtor-name> ::= C1
1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= C2
1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= C3
1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= D0
1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= D1
1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= D2
1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_ctor_dtor_name (struct d_info *di)
1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (di->last_name != NULL)
1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (di->last_name->type == DEMANGLE_COMPONENT_NAME)
1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion += di->last_name->u.s_name.len;
1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD)
1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion += di->last_name->u.s_string.len;
1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (d_peek_char (di))
1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'C':
1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	enum gnu_v3_ctor_kinds kind;
1815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	switch (d_peek_next_char (di))
1817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '1':
1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_complete_object_ctor;
1820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
1821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '2':
1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_base_object_ctor;
1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '3':
1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_complete_object_allocating_ctor;
1826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
1827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  default:
1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_advance (di, 2);
1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_ctor (di, kind, di->last_name);
1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'D':
1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	enum gnu_v3_dtor_kinds kind;
1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	switch (d_peek_next_char (di))
1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '0':
1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_deleting_dtor;
1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '1':
1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_complete_object_dtor;
1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
1846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '2':
1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_base_object_dtor;
1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
1849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  default:
1850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_advance (di, 2);
1853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_dtor (di, kind, di->last_name);
1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
1858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <type> ::= <builtin-type>
1862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <function-type>
1863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <class-enum-type>
1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <array-type>
1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <pointer-to-member-type>
1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <template-param>
1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <template-template-param> <template-args>
1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <substitution>
1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <CV-qualifiers> <type>
1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= P <type>
1871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= R <type>
1872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= O <type> (C++0x)
1873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= C <type>
1874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= G <type>
1875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= U <source-name> <type>
1876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <builtin-type> ::= various one letter codes
1878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= u <source-name>
1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst struct demangle_builtin_type_info
1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] =
1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* a */ { NL ("signed char"),	NL ("signed char"),	D_PRINT_DEFAULT },
1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* b */ { NL ("bool"),	NL ("boolean"),		D_PRINT_BOOL },
1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* c */ { NL ("char"),	NL ("byte"),		D_PRINT_DEFAULT },
1888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* d */ { NL ("double"),	NL ("double"),		D_PRINT_FLOAT },
1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* e */ { NL ("long double"),	NL ("long double"),	D_PRINT_FLOAT },
1890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* f */ { NL ("float"),	NL ("float"),		D_PRINT_FLOAT },
1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* g */ { NL ("__float128"),	NL ("__float128"),	D_PRINT_FLOAT },
1892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* h */ { NL ("unsigned char"), NL ("unsigned char"),	D_PRINT_DEFAULT },
1893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* i */ { NL ("int"),		NL ("int"),		D_PRINT_INT },
1894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* j */ { NL ("unsigned int"), NL ("unsigned"),	D_PRINT_UNSIGNED },
1895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* k */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
1896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* l */ { NL ("long"),	NL ("long"),		D_PRINT_LONG },
1897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* m */ { NL ("unsigned long"), NL ("unsigned long"),	D_PRINT_UNSIGNED_LONG },
1898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* n */ { NL ("__int128"),	NL ("__int128"),	D_PRINT_DEFAULT },
1899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"),
1900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    D_PRINT_DEFAULT },
1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* p */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* q */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* r */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* s */ { NL ("short"),	NL ("short"),		D_PRINT_DEFAULT },
1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT },
1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* u */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* v */ { NL ("void"),	NL ("void"),		D_PRINT_VOID },
1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* w */ { NL ("wchar_t"),	NL ("char"),		D_PRINT_DEFAULT },
1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* x */ { NL ("long long"),	NL ("long"),		D_PRINT_LONG_LONG },
1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* y */ { NL ("unsigned long long"), NL ("unsigned long long"),
1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    D_PRINT_UNSIGNED_LONG_LONG },
1912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* z */ { NL ("..."),		NL ("..."),		D_PRINT_DEFAULT },
1913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 26 */ { NL ("decimal32"),	NL ("decimal32"),	D_PRINT_DEFAULT },
1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 27 */ { NL ("decimal64"),	NL ("decimal64"),	D_PRINT_DEFAULT },
1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 28 */ { NL ("decimal128"),	NL ("decimal128"),	D_PRINT_DEFAULT },
1916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 29 */ { NL ("half"),	NL ("half"),		D_PRINT_FLOAT },
1917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 30 */ { NL ("char16_t"),	NL ("char16_t"),	D_PRINT_DEFAULT },
1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 31 */ { NL ("char32_t"),	NL ("char32_t"),	D_PRINT_DEFAULT },
1919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
1920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct demangle_component *
1923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_type (struct d_info *di)
1924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
1926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret = NULL;
1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int can_subst;
1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The ABI specifies that when CV-qualifiers are used, the base type
1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     is substitutable, and the fully qualified type is substitutable,
1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     but the base type with a strict subset of the CV-qualifiers is
1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     not substitutable.  The natural recursive implementation of the
1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     CV-qualifiers would cause subsets to be substitutable, so instead
1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     we pull them all off now.
1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     FIXME: The ABI says that order-insensitive vendor qualifiers
1937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     should be handled in the same way, but we have no way to tell
1938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     which vendor qualifiers are order-insensitive and which are
1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     order-sensitive.  So we just assume that they are all
1940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     order-sensitive.  g++ 3.4 supports only one vendor qualifier,
1941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     __vector, and it treats it as order-sensitive when mangling
1942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     names.  */
1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
1945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == 'r' || peek == 'V' || peek == 'K')
1946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component **pret;
1948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pret = d_cv_qualifiers (di, &ret, 0);
1950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (pret == NULL)
1951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *pret = cplus_demangle_type (di);
1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! *pret || ! d_add_substitution (di, ret))
1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ret;
1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  can_subst = 1;
1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (peek)
1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
1963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'h': case 'i': case 'j':           case 'l': case 'm': case 'n':
1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'o':                               case 's': case 't':
1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'v': case 'w': case 'x': case 'y': case 'z':
1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_builtin_type (di,
1967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				 &cplus_demangle_builtin_types[peek - 'a']);
1968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      di->expansion += ret->u.s_builtin.type->len;
1969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      can_subst = 0;
1970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
1971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'u':
1974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
1975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE,
1976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 d_source_name (di), NULL);
1977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'F':
1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_function_type (di);
1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case '0': case '1': case '2': case '3': case '4':
1984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case '5': case '6': case '7': case '8': case '9':
1985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'N':
1986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'Z':
1987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_class_enum_type (di);
1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'A':
1991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_array_type (di);
1992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'M':
1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_pointer_to_member_type (di);
1996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'T':
1999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_template_param (di);
2000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'I')
2001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* This is <template-template-param> <template-args>.  The
2003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     <template-template-param> part is a substitution
2004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     candidate.  */
2005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_add_substitution (di, ret))
2006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
2007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			     d_template_args (di));
2009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'S':
2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If this is a special substitution, then it is the start of
2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 <class-enum-type>.  */
2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	char peek_next;
2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	peek_next = d_peek_next_char (di);
2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (IS_DIGIT (peek_next)
2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    || peek_next == '_'
2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    || IS_UPPER (peek_next))
2022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
2023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = d_substitution (di, 0);
2024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* The substituted name may have been a template name and
2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       may be followed by tepmlate args.  */
2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (d_peek_char (di) == 'I')
2027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				 d_template_args (di));
2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    else
2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      can_subst = 0;
2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	else
2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = d_class_enum_type (di);
2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* If the substitution was a complete type, then it is not
2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       a new substitution candidate.  However, if the
2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       substitution was followed by template arguments, then
2038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       the whole thing is a substitution candidate.  */
2039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (ret != NULL && ret->type == DEMANGLE_COMPONENT_SUB_STD)
2040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      can_subst = 0;
2041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'O':
2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_RVALUE_REFERENCE,
2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cplus_demangle_type (di), NULL);
2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'P':
2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_POINTER,
2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 cplus_demangle_type (di), NULL);
2055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'R':
2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_REFERENCE,
2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cplus_demangle_type (di), NULL);
2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'C':
2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_COMPLEX,
2066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 cplus_demangle_type (di), NULL);
2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'G':
2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_IMAGINARY,
2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 cplus_demangle_type (di), NULL);
2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'U':
2076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_source_name (di);
2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 cplus_demangle_type (di), ret);
2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'D':
2083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      can_subst = 0;
2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_next_char (di);
2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (peek)
2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'T':
2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 't':
2090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* decltype (expression) */
2091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_comp (di, DEMANGLE_COMPONENT_DECLTYPE,
2092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			     d_expression (di), NULL);
2093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (ret && d_next_char (di) != 'E')
2094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = NULL;
2095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'p':
2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* Pack expansion.  */
2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			     cplus_demangle_type (di), NULL);
2101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'f':
2104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* 32-bit decimal floating point */
2105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
2106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'd':
2109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* 64-bit DFP */
2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[27]);
2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'e':
2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* 128-bit DFP */
2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[28]);
2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'h':
2119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* 16-bit half-precision FP */
2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[29]);
2121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 's':
2124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* char16_t */
2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]);
2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'i':
2129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* char32_t */
2130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
2131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
2137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
2138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (can_subst)
2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_add_substitution (di, ret))
2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
2147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <CV-qualifiers> ::= [r] [V] [K]  */
2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component **
2152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_cv_qualifiers (struct d_info *di,
2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 struct demangle_component **pret, int member_fn)
2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
2156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (peek == 'r' || peek == 'V' || peek == 'K')
2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      enum demangle_component_type t;
2161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (peek == 'r')
2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  t = (member_fn
2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       ? DEMANGLE_COMPONENT_RESTRICT_THIS
2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       : DEMANGLE_COMPONENT_RESTRICT);
2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += sizeof "restrict";
2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'V')
2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  t = (member_fn
2173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       ? DEMANGLE_COMPONENT_VOLATILE_THIS
2174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       : DEMANGLE_COMPONENT_VOLATILE);
2175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += sizeof "volatile";
2176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  t = (member_fn
2180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       ? DEMANGLE_COMPONENT_CONST_THIS
2181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       : DEMANGLE_COMPONENT_CONST);
2182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += sizeof "const";
2183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *pret = d_make_comp (di, t, NULL, NULL);
2186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (*pret == NULL)
2187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pret = &d_left (*pret);
2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return pret;
2194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <function-type> ::= F [Y] <bare-function-type> E  */
2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_function_type (struct d_info *di)
2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'F'))
2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == 'Y')
2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Function has C linkage.  We don't print this information.
2208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 FIXME: We should print it in verbose mode.  */
2209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ret = d_bare_function_type (di, 1);
2212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'E'))
2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <bare-function-type> ::= [J]<type>+  */
2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_bare_function_type (struct d_info *di, int has_return_tipe)
2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *return_type;
2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *tl;
2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **ptl;
2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Detect special qualifier indicating that the first argument
2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     is the return type.  */
2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == 'J')
2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      has_return_tipe = 1;
2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return_type = NULL;
2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  tl = NULL;
2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ptl = &tl;
2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *type;
2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (peek == '\0' || peek == 'E')
2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	break;
2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      type = cplus_demangle_type (di);
2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (type == NULL)
2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (has_return_tipe)
2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return_type = type;
2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  has_return_tipe = 0;
2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL);
2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (*ptl == NULL)
2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ptl = &d_right (*ptl);
2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* There should be at least one parameter type besides the optional
2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     return type.  A function which takes no arguments will have a
2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     single parameter type void.  */
2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (tl == NULL)
2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* If we have a single parameter type void, omit it.  */
2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_right (tl) == NULL
2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      && d_left (tl)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      && d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID)
2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      di->expansion -= d_left (tl)->u.s_builtin.type->len;
2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tl = NULL;
2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE, return_type, tl);
2279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <class-enum-type> ::= <name>  */
2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_class_enum_type (struct d_info *di)
2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_name (di);
2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <array-type> ::= A <(positive dimension) number> _ <(element) type>
2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= A [<(dimension) expression>] _ <(element) type>
2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_array_type (struct d_info *di)
2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *dim;
2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'A'))
2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == '_')
2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    dim = NULL;
2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (IS_DIGIT (peek))
2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const char *s;
2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      s = d_str (di);
2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      do
2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  peek = d_peek_char (di);
2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (IS_DIGIT (peek));
2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dim = d_make_name (di, s, d_str (di) - s);
2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dim == NULL)
2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dim = d_expression (di);
2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dim == NULL)
2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, '_'))
2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim,
2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      cplus_demangle_type (di));
2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <pointer-to-member-type> ::= M <(class) type> <(member) type>  */
2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_pointer_to_member_type (struct d_info *di)
2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *cl;
2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *mem;
2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **pmem;
2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'M'))
2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  cl = cplus_demangle_type (di);
2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The ABI specifies that any type can be a substitution source, and
2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     that M is followed by two types, and that when a CV-qualified
2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     type is seen both the base type and the CV-qualified types are
2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     substitution sources.  The ABI also specifies that for a pointer
2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     to a CV-qualified member function, the qualifiers are attached to
2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     the second type.  Given the grammar, a plain reading of the ABI
2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     suggests that both the CV-qualified member function and the
2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     non-qualified member function are substitution sources.  However,
2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     g++ does not work that way.  g++ treats only the CV-qualified
2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     member function as a substitution source.  FIXME.  So to work
2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     with g++, we need to pull off the CV-qualifiers here, in order to
2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     avoid calling add_substitution() in cplus_demangle_type().  But
2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     for a CV-qualified member which is not a function, g++ does
2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     follow the ABI, so we need to handle that case here by calling
2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     d_add_substitution ourselves.  */
2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pmem = d_cv_qualifiers (di, &mem, 1);
2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (pmem == NULL)
2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *pmem = cplus_demangle_type (di);
2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (*pmem == NULL)
2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_add_substitution (di, mem))
2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <template-param> ::= T_
2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= T <(parameter-2 non-negative) number> _
2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_param (struct d_info *di)
2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long param;
2388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'T'))
2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == '_')
2393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    param = 0;
2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      param = d_number (di);
2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (param < 0)
2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      param += 1;
2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, '_'))
2403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ++di->did_subs;
2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_make_template_param (di, param);
2408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <template-args> ::= I <template-arg>+ E  */
2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_args (struct d_info *di)
2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *hold_last_name;
2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *al;
2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **pal;
2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Preserve the last name we saw--don't let the template arguments
2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     clobber it, as that would give us the wrong name for a subsequent
2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     constructor or destructor.  */
2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hold_last_name = di->last_name;
2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'I'))
2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == 'E')
2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* An argument pack can be empty.  */
2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, NULL, NULL);
2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  al = NULL;
2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pal = &al;
2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *a;
2439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = d_template_arg (di);
2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (a == NULL)
2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *pal = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, a, NULL);
2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (*pal == NULL)
2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pal = &d_right (*pal);
2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'E')
2450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->last_name = hold_last_name;
2457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return al;
2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <template-arg> ::= <type>
2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= X <expression> E
2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= <expr-primary>
2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_arg (struct d_info *di)
2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (d_peek_char (di))
2472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'X':
2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_expression (di);
2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_check_char (di, 'E'))
2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ret;
2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'L':
2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_expr_primary (di);
2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'I':
2484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* An argument pack.  */
2485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_template_args (di);
2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
2488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return cplus_demangle_type (di);
2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Subroutine of <expression> ::= cl <expression>+ E */
2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_exprlist (struct d_info *di)
2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *list = NULL;
2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **p = &list;
2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == 'E')
2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL);
2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
2507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *arg = d_expression (di);
2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (arg == NULL)
2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *p = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, arg, NULL);
2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (*p == NULL)
2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p = &d_right (*p);
2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'E')
2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return list;
2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <expression> ::= <(unary) operator-name> <expression>
2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= <(binary) operator-name> <expression> <expression>
2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= <(trinary) operator-name> <expression> <expression> <expression>
2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		::= cl <expression>+ E
2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= st <type>
2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= <template-param>
2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= sr <type> <unqualified-name>
2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= sr <type> <unqualified-name> <template-args>
2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= <expr-primary>
2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_expression (struct d_info *di)
2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
2542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
2544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == 'L')
2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_expr_primary (di);
2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (peek == 'T')
2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_template_param (di);
2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (peek == 's' && d_peek_next_char (di) == 'r')
2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *type;
2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *name;
2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 2);
2554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      type = cplus_demangle_type (di);
2555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      name = d_unqualified_name (di);
2556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) != 'I')
2557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name);
2558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type,
2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					 d_template_args (di)));
2562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (peek == 's' && d_peek_next_char (di) == 'T')
2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Just demangle a parameter placeholder as its type.  */
2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 2);
2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return cplus_demangle_type (di);
2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (IS_DIGIT (peek))
2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We can get an unqualified name as an expression in the case of
2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         a dependent member access, i.e. decltype(T().i).  */
2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *name = d_unqualified_name (di);
2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (name == NULL)
2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'I')
2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    d_template_args (di));
2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return name;
2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *op;
2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int args;
2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      op = d_operator_name (di);
2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (op == NULL)
2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (op->type == DEMANGLE_COMPONENT_OPERATOR)
2592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion += op->u.s_operator.op->len - 2;
2593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (op->type == DEMANGLE_COMPONENT_OPERATOR
2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && strcmp (op->u.s_operator.op->code, "st") == 0)
2596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    cplus_demangle_type (di));
2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (op->type)
2600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return NULL;
2603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_OPERATOR:
2604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  args = op->u.s_operator.op->args;
2605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  args = op->u.s_extended_operator.args;
2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_CAST:
2610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (d_peek_char (di) == 'v')
2611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* T() encoded as an operand of void.  */
2612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				cplus_demangle_type (di));
2614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  else
2615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    args = 1;
2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (args)
2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 1:
2622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
2623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_expression (di));
2624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 2:
2625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
2626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *left;
2627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *right;
2628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    left = d_expression (di);
2630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (!strcmp (op->u.s_operator.op->code, "cl"))
2631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      right = d_exprlist (di);
2632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    else
2633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      right = d_expression (di);
2634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op,
2636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				d_make_comp (di,
2637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     DEMANGLE_COMPONENT_BINARY_ARGS,
2638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     left, right));
2639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
2640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 3:
2641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
2642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *first;
2643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *second;
2644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    first = d_expression (di);
2646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    second = d_expression (di);
2647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op,
2648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				d_make_comp (di,
2649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     DEMANGLE_COMPONENT_TRINARY_ARG1,
2650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     first,
2651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     d_make_comp (di,
2652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown							  DEMANGLE_COMPONENT_TRINARY_ARG2,
2653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown							  second,
2654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown							  d_expression (di))));
2655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
2656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
2657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return NULL;
2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <expr-primary> ::= L <type> <(value) number> E
2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= L <type> <(value) float> E
2664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= L <mangled-name> E
2665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_expr_primary (struct d_info *di)
2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
2671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'L'))
2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == '_')
2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ret = cplus_demangle_mangled_name (di, 0);
2676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
2677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *type;
2679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      enum demangle_component_type t;
2680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const char *s;
2681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      type = cplus_demangle_type (di);
2683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (type == NULL)
2684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If we have a type we know how to print, we aren't going to
2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 print the type name itself.  */
2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && type->u.s_builtin.type->print != D_PRINT_DEFAULT)
2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion -= type->u.s_builtin.type->len;
2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Rather than try to interpret the literal value, we just
2693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 collect it as a string.  Note that it's possible to have a
2694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 floating point literal here.  The ABI specifies that the
2695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 format of such literals is machine independent.  That's fine,
2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 but what's not fine is that versions of g++ up to 3.2 with
2697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 -fabi-version=1 used upper case letters in the hex constant,
2698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 and dumped out gcc's internal representation.  That makes it
2699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 hard to tell where the constant ends, and hard to dump the
2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 constant in any readable form anyhow.  We don't attempt to
2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 handle these cases.  */
2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      t = DEMANGLE_COMPONENT_LITERAL;
2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'n')
2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  t = DEMANGLE_COMPONENT_LITERAL_NEG;
2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      s = d_str (di);
2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (d_peek_char (di) != 'E')
2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (d_peek_char (di) == '\0')
2713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
2714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
2715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s));
2717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'E'))
2719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
2721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <local-name> ::= Z <(function) encoding> E <(entity) name> [<discriminator>]
2724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= Z <(function) encoding> E s [<discriminator>]
2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_local_name (struct d_info *di)
2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *function;
2731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'Z'))
2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  function = d_encoding (di, 0);
2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'E'))
2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == 's')
2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_discriminator (di))
2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function,
2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			  d_make_name (di, "string literal",
2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				       sizeof "string literal" - 1));
2748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *name;
2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      name = d_name (di);
2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_discriminator (di))
2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name);
2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <discriminator> ::= _ <(non-negative) number>
2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   We demangle the discriminator, but we don't print it out.  FIXME:
2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   We should print it out in verbose mode.  */
2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_discriminator (struct d_info *di)
2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long discrim;
2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) != '_')
2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 1;
2772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_advance (di, 1);
2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  discrim = d_number (di);
2774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (discrim < 0)
2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new substitution.  */
2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_add_substitution (struct d_info *di, struct demangle_component *dc)
2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (di->next_sub >= di->num_subs)
2787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
2788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->subs[di->next_sub] = dc;
2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ++di->next_sub;
2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <substitution> ::= S <seq-id> _
2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= S_
2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= St
2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Sa
2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Sb
2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Ss
2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Si
2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= So
2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Sd
2802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   If PREFIX is non-zero, then this type is being used as a prefix in
2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a qualified name.  In this case, for the standard substitutions, we
2805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   need to check whether we are being used as a prefix for a
2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   constructor or destructor, and return a full template name.
2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Otherwise we will get something like std::iostream::~iostream()
2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   which does not correspond particularly well to any function which
2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   actually appears in the source.
2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const struct d_standard_sub_info standard_subs[] =
2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 't', NL ("std"),
2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std"),
2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NULL, 0 },
2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'a', NL ("std::allocator"),
2818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::allocator"),
2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("allocator") },
2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'b', NL ("std::basic_string"),
2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_string"),
2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_string") },
2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 's', NL ("std::string"),
2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_string") },
2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'i', NL ("std::istream"),
2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_istream<char, std::char_traits<char> >"),
2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_istream") },
2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'o', NL ("std::ostream"),
2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_ostream<char, std::char_traits<char> >"),
2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_ostream") },
2832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'd', NL ("std::iostream"),
2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_iostream<char, std::char_traits<char> >"),
2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_iostream") }
2835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
2836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_substitution (struct d_info *di, int prefix)
2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char c;
2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'S'))
2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  c = d_next_char (di);
2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (c == '_' || IS_DIGIT (c) || IS_UPPER (c))
2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned int id;
2849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      id = 0;
2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (c != '_')
2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  do
2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      unsigned int new_id;
2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (IS_DIGIT (c))
2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		new_id = id * 36 + c - '0';
2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else if (IS_UPPER (c))
2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		new_id = id * 36 + c - 'A' + 10;
2861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
2862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		return NULL;
2863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (new_id < id)
2864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		return NULL;
2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      id = new_id;
2866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = d_next_char (di);
2867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  while (c != '_');
2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ++id;
2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (id >= (unsigned int) di->next_sub)
2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ++di->did_subs;
2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return di->subs[id];
2879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
2881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int verbose;
2883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const struct d_standard_sub_info *p;
2884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const struct d_standard_sub_info *pend;
2885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      verbose = (di->options & DMGL_VERBOSE) != 0;
2887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! verbose && prefix)
2888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  char peek;
2890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  peek = d_peek_char (di);
2892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (peek == 'C' || peek == 'D')
2893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    verbose = 1;
2894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pend = (&standard_subs[0]
2897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      + sizeof standard_subs / sizeof standard_subs[0]);
2898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (p = &standard_subs[0]; p < pend; ++p)
2899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (c == p->code)
2901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
2902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      const char *s;
2903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      int len;
2904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (p->set_last_name != NULL)
2906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		di->last_name = d_make_sub (di, p->set_last_name,
2907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					    p->set_last_name_len);
2908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (verbose)
2909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
2910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  s = p->full_expansion;
2911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  len = p->full_len;
2912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
2913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
2914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
2915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  s = p->simple_expansion;
2916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  len = p->simple_len;
2917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
2918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      di->expansion += len;
2919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return d_make_sub (di, s, len);
2920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
2921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
2924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialize a growable string.  */
2928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
2930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_init (struct d_growable_string *dgs, size_t estimate)
2931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->buf = NULL;
2933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->len = 0;
2934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->alc = 0;
2935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->allocation_failure = 0;
2936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (estimate > 0)
2938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_growable_string_resize (dgs, estimate);
2939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Grow a growable string to a given size.  */
2942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
2944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_resize (struct d_growable_string *dgs, size_t need)
2945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t newalc;
2947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char *newbuf;
2948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dgs->allocation_failure)
2950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return;
2951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Start allocation at two bytes to avoid any possibility of confusion
2953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     with the special value of 1 used as a return in *palc to indicate
2954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     allocation failures.  */
2955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  newalc = dgs->alc > 0 ? dgs->alc : 2;
2956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (newalc < need)
2957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    newalc <<= 1;
2958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  newbuf = (char *) realloc ("demangle.dgsr.1", dgs->buf, newalc);
2960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (newbuf == NULL)
2961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      free (dgs->buf);
2963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dgs->buf = NULL;
2964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dgs->len = 0;
2965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dgs->alc = 0;
2966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dgs->allocation_failure = 1;
2967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
2968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->buf = newbuf;
2970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->alc = newalc;
2971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append a buffer to a growable string.  */
2974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
2976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_append_buffer (struct d_growable_string *dgs,
2977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 const char *s, size_t l)
2978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t need;
2980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  need = dgs->len + l + 1;
2982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (need > dgs->alc)
2983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_growable_string_resize (dgs, need);
2984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dgs->allocation_failure)
2986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return;
2987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  memcpy (dgs->buf + dgs->len, s, l);
2989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->buf[dgs->len + l] = '\0';
2990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->len += l;
2991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Bridge growable strings to the callback mechanism.  */
2994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
2996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_callback_adapter (const char *s, size_t l, void *opaque)
2997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_growable_string *dgs = (struct d_growable_string*) opaque;
2999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_growable_string_append_buffer (dgs, s, l);
3001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialize a print information structure.  */
3004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
3006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_init (struct d_print_info *dpi, int options,
3007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              demangle_callbackref callback, void *opaque)
3008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->options = options;
3010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->len = 0;
3011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->last_char = '\0';
3012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->templates = NULL;
3013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->modifiers = NULL;
3014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->callback = callback;
3016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->opaque = opaque;
3017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->demangle_failure = 0;
3019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Indicate that an error occurred during printing, and test for error.  */
3022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_error (struct d_print_info *dpi)
3025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->demangle_failure = 1;
3027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline int
3030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_saw_error (struct d_print_info *dpi)
3031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dpi->demangle_failure != 0;
3033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Flush buffered characters to the callback.  */
3036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_flush (struct d_print_info *dpi)
3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->buf[dpi->len] = '\0';
3041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->callback (dpi->buf, dpi->len, dpi->opaque);
3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->len = 0;
3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append characters and buffers for printing.  */
3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_append_char (struct d_print_info *dpi, char c)
3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dpi->len == sizeof (dpi->buf) - 1)
3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_print_flush (dpi);
3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->buf[dpi->len++] = c;
3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->last_char = c;
3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_append_buffer (struct d_print_info *dpi, const char *s, size_t l)
3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t i;
3061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (i = 0; i < l; i++)
3063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, s[i]);
3064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_append_string (struct d_print_info *dpi, const char *s)
3068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_buffer (dpi, s, strlen (s));
3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline char
3073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_last_char (struct d_print_info *dpi)
3074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dpi->last_char;
3076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Turn components into a human readable string.  OPTIONS is the
3079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   options bits passed to the demangler.  DC is the tree to print.
3080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CALLBACK is a function to call to flush demangled string segments
3081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   as they fill the intermediate buffer, and OPAQUE is a generalized
3082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   callback argument.  On success, this returns 1.  On failure,
3083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   it returns 0, indicating a bad parse.  It does not use heap
3084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   memory to build an output string, so cannot encounter memory
3085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   allocation failure.  */
3086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
3088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_print_callback (int options,
3090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               const struct demangle_component *dc,
3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               demangle_callbackref callback, void *opaque)
3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_info dpi;
3094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_print_init (&dpi, options, callback, opaque);
3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_print_comp (&dpi, dc);
3098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_print_flush (&dpi);
3100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ! d_print_saw_error (&dpi);
3102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Turn components into a human readable string.  OPTIONS is the
3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   options bits passed to the demangler.  DC is the tree to print.
3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ESTIMATE is a guess at the length of the result.  This returns a
3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   string allocated by malloc, or NULL on error.  On success, this
3108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sets *PALC to the size of the allocated buffer.  On failure, this
3109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sets *PALC to 0 for a bad parse, or to 1 for a memory allocation
3110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   failure.  */
3111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
3113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar *
3114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_print (int options, const struct demangle_component *dc,
3115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      int estimate, size_t *palc)
3116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_growable_string dgs;
3118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_growable_string_init (&dgs, estimate);
3120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_print_callback (options, dc,
3122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                       d_growable_string_callback_adapter,
3123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                       &dgs))
3124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      free (dgs.buf);
3126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *palc = 0;
3127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *palc = dgs.allocation_failure ? 1 : dgs.alc;
3131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dgs.buf;
3132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns the I'th element of the template arglist ARGS, or NULL on
3135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   failure.  */
3136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
3138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_index_template_argument (struct demangle_component *args, int i)
3139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *a;
3141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (a = args;
3143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       a != NULL;
3144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       a = d_right (a))
3145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
3147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
3148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i <= 0)
3149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	break;
3150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      --i;
3151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (i != 0 || a == NULL)
3153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
3154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_left (a);
3156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns the template argument from the current context indicated by DC,
3159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   which is a DEMANGLE_COMPONENT_TEMPLATE_PARAM, or NULL.  */
3160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
3162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_lookup_template_argument (struct d_print_info *dpi,
3163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    const struct demangle_component *dc)
3164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dpi->templates == NULL)
3166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
3168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_index_template_argument
3172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (d_right (dpi->templates->template_decl),
3173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     dc->u.s_number.number);
3174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns a template argument pack used in DC (any will do), or NULL.  */
3177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
3179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_find_pack (struct d_print_info *dpi,
3180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     const struct demangle_component *dc)
3181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *a;
3183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
3184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
3185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
3187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
3189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = d_lookup_template_argument (dpi, dc);
3190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
3191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return a;
3192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PACK_EXPANSION:
3195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_NAME:
3198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_OPERATOR:
3199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
3200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_SUB_STD:
3201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CHARACTER:
3202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
3205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_find_pack (dpi, dc->u.s_extended_operator.name);
3206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CTOR:
3207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_find_pack (dpi, dc->u.s_ctor.name);
3208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DTOR:
3209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_find_pack (dpi, dc->u.s_dtor.name);
3210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
3212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = d_find_pack (dpi, d_left (dc));
3213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (a)
3214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return a;
3215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_find_pack (dpi, d_right (dc));
3216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns the length of the template argument pack DC.  */
3220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
3222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_pack_length (const struct demangle_component *dc)
3223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int count = 0;
3225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST
3226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 && d_left (dc) != NULL)
3227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ++count;
3229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = d_right (dc);
3230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return count;
3232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DC is a component of a mangled expression.  Print it, wrapped in parens
3235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if needed.  */
3236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
3238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_subexpr (struct d_print_info *dpi,
3239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		 const struct demangle_component *dc)
3240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int simple = 0;
3242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc->type == DEMANGLE_COMPONENT_NAME)
3243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    simple = 1;
3244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (!simple)
3245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, '(');
3246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_print_comp (dpi, dc);
3247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (!simple)
3248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, ')');
3249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Subroutine to handle components.  */
3252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
3254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_comp (struct d_print_info *dpi,
3255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              const struct demangle_component *dc)
3256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
3258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
3260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_print_saw_error (dpi))
3263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return;
3264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
3266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_NAME:
3268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((dpi->options & DMGL_JAVA) == 0)
3269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_buffer (dpi, dc->u.s_name.s, dc->u.s_name.len);
3270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
3271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_java_identifier (dpi, dc->u.s_name.s, dc->u.s_name.len);
3272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_QUAL_NAME:
3275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LOCAL_NAME:
3276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((dpi->options & DMGL_JAVA) == 0)
3278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_string (dpi, "::");
3279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
3280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '.');
3281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_right (dc));
3282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPED_NAME:
3285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *hold_modifiers;
3287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct demangle_component *typed_name;
3288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod adpm[4];
3289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	unsigned int i;
3290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_template dpt;
3291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* Pass the name down to the type so that it can be printed in
3293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   the right place for the type.  We also have to pass down
3294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   any CV-qualifiers, which apply to the this parameter.  */
3295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	hold_modifiers = dpi->modifiers;
3296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	i = 0;
3297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	typed_name = d_left (dc);
3298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	while (typed_name != NULL)
3299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (i >= sizeof adpm / sizeof adpm[0])
3301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
3302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		d_print_error (dpi);
3303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		return;
3304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    adpm[i].next = dpi->modifiers;
3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->modifiers = &adpm[i];
3308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    adpm[i].mod = typed_name;
3309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    adpm[i].printed = 0;
3310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    adpm[i].templates = dpi->templates;
3311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ++i;
3312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS
3314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		&& typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS
3315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		&& typed_name->type != DEMANGLE_COMPONENT_CONST_THIS)
3316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      break;
3317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    typed_name = d_left (typed_name);
3319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (typed_name == NULL)
3322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_error (dpi);
3324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return;
3325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If typed_name is a template, then it applies to the
3328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   function type as well.  */
3329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
3330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpt.next = dpi->templates;
3332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->templates = &dpt;
3333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpt.template_decl = typed_name;
3334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If typed_name is a DEMANGLE_COMPONENT_LOCAL_NAME, then
3337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   there may be CV-qualifiers on its right argument which
3338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   really apply here; this happens when parsing a class which
3339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   is local to a function.  */
3340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (typed_name->type == DEMANGLE_COMPONENT_LOCAL_NAME)
3341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *local_name;
3343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    local_name = d_right (typed_name);
3345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
3346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
3347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   || local_name->type == DEMANGLE_COMPONENT_CONST_THIS)
3348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
3349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (i >= sizeof adpm / sizeof adpm[0])
3350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
3351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    d_print_error (dpi);
3352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    return;
3353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
3354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i] = adpm[i - 1];
3356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i].next = &adpm[i - 1];
3357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dpi->modifiers = &adpm[i];
3358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i - 1].mod = local_name;
3360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i - 1].printed = 0;
3361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i - 1].templates = dpi->templates;
3362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		++i;
3363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		local_name = d_left (local_name);
3365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
3366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_comp (dpi, d_right (dc));
3369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
3371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  dpi->templates = dpt.next;
3372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If the modifiers didn't get printed by the type, print them
3374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   now.  */
3375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	while (i > 0)
3376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    --i;
3378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! adpm[i].printed)
3379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
3380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		d_append_char (dpi, ' ');
3381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		d_print_mod (dpi, adpm[i].mod);
3382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
3383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = hold_modifiers;
3386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE:
3391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *hold_dpm;
3393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct demangle_component *dcl;
3394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* Don't push modifiers into a template definition.  Doing so
3396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   could give the wrong definition for a template argument.
3397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   Instead, treat the template essentially as a name.  */
3398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	hold_dpm = dpi->modifiers;
3400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = NULL;
3401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        dcl = d_left (dc);
3403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ((dpi->options & DMGL_JAVA) != 0
3405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            && dcl->type == DEMANGLE_COMPONENT_NAME
3406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            && dcl->u.s_name.len == 6
3407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            && strncmp (dcl->u.s_name.s, "JArray", 6) == 0)
3408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          {
3409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* Special-case Java arrays, so that JArray<TYPE> appears
3410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               instead as TYPE[].  */
3411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            d_print_comp (dpi, d_right (dc));
3413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            d_append_string (dpi, "[]");
3414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          }
3415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else
3416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          {
3417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_comp (dpi, dcl);
3418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (d_last_char (dpi) == '<')
3419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_char (dpi, ' ');
3420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_append_char (dpi, '<');
3421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_comp (dpi, d_right (dc));
3422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* Avoid generating two consecutive '>' characters, to avoid
3423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       the C++ syntactic ambiguity.  */
3424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (d_last_char (dpi) == '>')
3425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_char (dpi, ' ');
3426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_append_char (dpi, '>');
3427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          }
3428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = hold_dpm;
3430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
3435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_template *hold_dpt;
3437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct demangle_component *a = d_lookup_template_argument (dpi, dc);
3438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
3440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  a = d_index_template_argument (a, dpi->pack_index);
3441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (a == NULL)
3443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_error (dpi);
3445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return;
3446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* While processing this parameter, we need to pop the list of
3449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   templates.  This is because the template parameter may
3450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   itself be a reference to a parameter of an outer
3451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   template.  */
3452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	hold_dpt = dpi->templates;
3454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->templates = hold_dpt->next;
3455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_comp (dpi, a);
3457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->templates = hold_dpt;
3459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CTOR:
3464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, dc->u.s_ctor.name);
3465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DTOR:
3468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '~');
3469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, dc->u.s_dtor.name);
3470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTABLE:
3473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "vtable for ");
3474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTT:
3478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "VTT for ");
3479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
3483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "construction vtable for ");
3484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "-in-");
3486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_right (dc));
3487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO:
3490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "typeinfo for ");
3491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_NAME:
3495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "typeinfo name for ");
3496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_FN:
3500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "typeinfo fn for ");
3501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_THUNK:
3505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "non-virtual thunk to ");
3506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
3510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "virtual thunk to ");
3511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COVARIANT_THUNK:
3515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "covariant return thunk to ");
3516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_CLASS:
3520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "java Class for ");
3521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_GUARD:
3525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "guard variable for ");
3526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFTEMP:
3530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "reference temporary for ");
3531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
3535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "hidden alias for ");
3536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_SUB_STD:
3540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_buffer (dpi, dc->u.s_string.string, dc->u.s_string.len);
3541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT:
3544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE:
3545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST:
3546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *pdpm;
3548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* When printing arrays, it's possible to have cases where the
3550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   same CV-qualifier gets pushed on the stack multiple times.
3551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   We only need to print it once.  */
3552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	for (pdpm = dpi->modifiers; pdpm != NULL; pdpm = pdpm->next)
3554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! pdpm->printed)
3556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
3557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (pdpm->mod->type != DEMANGLE_COMPONENT_RESTRICT
3558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    && pdpm->mod->type != DEMANGLE_COMPONENT_VOLATILE
3559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    && pdpm->mod->type != DEMANGLE_COMPONENT_CONST)
3560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  break;
3561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (pdpm->mod->type == dc->type)
3562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
3563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    d_print_comp (dpi, d_left (dc));
3564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    return;
3565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
3566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
3567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Fall through.  */
3570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
3571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
3572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
3573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
3574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_POINTER:
3575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFERENCE:
3576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
3577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPLEX:
3578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_IMAGINARY:
3579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* We keep a list of modifiers on the stack.  */
3581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod dpm;
3582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.next = dpi->modifiers;
3584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = &dpm;
3585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.mod = dc;
3586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.printed = 0;
3587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.templates = dpi->templates;
3588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_comp (dpi, d_left (dc));
3590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If the modifier didn't get printed by the type, print it
3592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   now.  */
3593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (! dpm.printed)
3594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_print_mod (dpi, dc);
3595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = dpm.next;
3597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
3602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((dpi->options & DMGL_JAVA) == 0)
3603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_buffer (dpi, dc->u.s_builtin.type->name,
3604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 dc->u.s_builtin.type->len);
3605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
3606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_buffer (dpi, dc->u.s_builtin.type->java_name,
3607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 dc->u.s_builtin.type->java_len);
3608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE:
3611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
3615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if ((dpi->options & DMGL_RET_POSTFIX) != 0)
3617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_print_function_type (dpi, dc, dpi->modifiers);
3618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* Print return type if present */
3620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (d_left (dc) != NULL)
3621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct d_print_mod dpm;
3623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* We must pass this type down as a modifier in order to
3625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       print it in the right location.  */
3626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpm.next = dpi->modifiers;
3627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->modifiers = &dpm;
3628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpm.mod = dc;
3629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpm.printed = 0;
3630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpm.templates = dpi->templates;
3631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_comp (dpi, d_left (dc));
3633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->modifiers = dpm.next;
3635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (dpm.printed)
3637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return;
3638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* In standard prefix notation, there is a space between the
3640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       return type and the function signature.  */
3641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if ((dpi->options & DMGL_RET_POSTFIX) == 0)
3642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_char (dpi, ' ');
3643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if ((dpi->options & DMGL_RET_POSTFIX) == 0)
3646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_print_function_type (dpi, dc, dpi->modifiers);
3647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARRAY_TYPE:
3652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *hold_modifiers;
3654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod adpm[4];
3655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	unsigned int i;
3656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *pdpm;
3657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* We must pass this type down as a modifier in order to print
3659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   multi-dimensional arrays correctly.  If the array itself is
3660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   CV-qualified, we act as though the element type were
3661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   CV-qualified.  We do this by copying the modifiers down
3662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   rather than fiddling pointers, so that we don't wind up
3663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   with a d_print_mod higher on the stack pointing into our
3664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   stack frame after we return.  */
3665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	hold_modifiers = dpi->modifiers;
3667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adpm[0].next = hold_modifiers;
3669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = &adpm[0];
3670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adpm[0].mod = dc;
3671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adpm[0].printed = 0;
3672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adpm[0].templates = dpi->templates;
3673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	i = 1;
3675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pdpm = hold_modifiers;
3676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	while (pdpm != NULL
3677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       && (pdpm->mod->type == DEMANGLE_COMPONENT_RESTRICT
3678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   || pdpm->mod->type == DEMANGLE_COMPONENT_VOLATILE
3679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   || pdpm->mod->type == DEMANGLE_COMPONENT_CONST))
3680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! pdpm->printed)
3682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
3683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (i >= sizeof adpm / sizeof adpm[0])
3684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
3685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    d_print_error (dpi);
3686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    return;
3687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
3688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i] = *pdpm;
3690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i].next = dpi->modifiers;
3691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dpi->modifiers = &adpm[i];
3692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		pdpm->printed = 1;
3693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		++i;
3694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
3695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    pdpm = pdpm->next;
3697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_comp (dpi, d_right (dc));
3700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = hold_modifiers;
3702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (adpm[0].printed)
3704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return;
3705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	while (i > 1)
3707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    --i;
3709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_mod (dpi, adpm[i].mod);
3710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_array_type (dpi, dc, dpi->modifiers);
3713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
3718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod dpm;
3720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.next = dpi->modifiers;
3722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = &dpm;
3723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.mod = dc;
3724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.printed = 0;
3725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.templates = dpi->templates;
3726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_comp (dpi, d_right (dc));
3728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If the modifier didn't get printed by the type, print it
3730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   now.  */
3731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (! dpm.printed)
3732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_append_char (dpi, ' ');
3734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_comp (dpi, d_left (dc));
3735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_append_string (dpi, "::*");
3736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = dpm.next;
3739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARGLIST:
3744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
3745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_left (dc) != NULL)
3746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_comp (dpi, d_left (dc));
3747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_right (dc) != NULL)
3748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_string (dpi, ", ");
3750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_print_comp (dpi, d_right (dc));
3751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
3752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_OPERATOR:
3755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	char c;
3757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_string (dpi, "operator");
3759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c = dc->u.s_operator.op->name[0];
3760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (IS_LOWER (c))
3761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, ' ');
3762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_buffer (dpi, dc->u.s_operator.op->name,
3763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 dc->u.s_operator.op->len);
3764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
3768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "operator ");
3769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, dc->u.s_extended_operator.name);
3770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CAST:
3773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "operator ");
3774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_cast (dpi, dc);
3775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_UNARY:
3778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST)
3779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_expr_op (dpi, d_left (dc));
3780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
3781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, '(');
3783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_print_cast (dpi, d_left (dc));
3784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, ')');
3785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
3786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_left (dc)->type == DEMANGLE_COMPONENT_CAST
3787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && d_right (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)
3788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* type() -- FIXME what about type(multiple,args) */
3789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_string (dpi, "()");
3790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
3791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_subexpr (dpi, d_right (dc));
3792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY:
3795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_right (dc)->type != DEMANGLE_COMPONENT_BINARY_ARGS)
3796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_print_error (dpi);
3798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return;
3799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
3800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We wrap an expression which uses the greater-than operator in
3802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 an extra layer of parens so that it does not get confused
3803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 with the '>' which ends the template parameters.  */
3804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
3805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && d_left (dc)->u.s_operator.op->len == 1
3806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && d_left (dc)->u.s_operator.op->name[0] == '>')
3807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '(');
3808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_subexpr (dpi, d_left (d_right (dc)));
3810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0)
3811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_expr_op (dpi, d_left (dc));
3812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_subexpr (dpi, d_right (d_right (dc)));
3813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
3815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && d_left (dc)->u.s_operator.op->len == 1
3816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && d_left (dc)->u.s_operator.op->name[0] == '>')
3817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ')');
3818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY_ARGS:
3822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We should only see this as part of DEMANGLE_COMPONENT_BINARY.  */
3823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
3824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY:
3827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_right (dc)->type != DEMANGLE_COMPONENT_TRINARY_ARG1
3828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  || d_right (d_right (dc))->type != DEMANGLE_COMPONENT_TRINARY_ARG2)
3829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_print_error (dpi);
3831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return;
3832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
3833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_subexpr (dpi, d_left (d_right (dc)));
3834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_expr_op (dpi, d_left (dc));
3835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_subexpr (dpi, d_left (d_right (d_right (dc))));
3836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, " : ");
3837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_subexpr (dpi, d_right (d_right (d_right (dc))));
3838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG1:
3841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG2:
3842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We should only see these are part of DEMANGLE_COMPONENT_TRINARY.  */
3843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
3844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL:
3847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL_NEG:
3848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	enum d_builtin_type_print tp;
3850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* For some builtin types, produce simpler output.  */
3852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	tp = D_PRINT_DEFAULT;
3853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (d_left (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)
3854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    tp = d_left (dc)->u.s_builtin.type->print;
3856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    switch (tp)
3857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
3858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_INT:
3859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_UNSIGNED:
3860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_LONG:
3861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_UNSIGNED_LONG:
3862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_LONG_LONG:
3863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_UNSIGNED_LONG_LONG:
3864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME)
3865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
3866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
3867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      d_append_char (dpi, '-');
3868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    d_print_comp (dpi, d_right (dc));
3869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    switch (tp)
3870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      {
3871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      default:
3872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
3873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_UNSIGNED:
3874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_char (dpi, 'u');
3875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
3876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_LONG:
3877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_char (dpi, 'l');
3878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
3879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_UNSIGNED_LONG:
3880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "ul");
3881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
3882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_LONG_LONG:
3883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "ll");
3884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
3885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_UNSIGNED_LONG_LONG:
3886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "ull");
3887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
3888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      }
3889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    return;
3890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
3891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
3892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_BOOL:
3894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME
3895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    && d_right (dc)->u.s_name.len == 1
3896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    && dc->type == DEMANGLE_COMPONENT_LITERAL)
3897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
3898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    switch (d_right (dc)->u.s_name.s[0])
3899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      {
3900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case '0':
3901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "false");
3902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			return;
3903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case '1':
3904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "true");
3905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			return;
3906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      default:
3907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
3908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      }
3909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
3910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
3911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      default:
3913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
3914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
3915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '(');
3918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_comp (dpi, d_left (dc));
3919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ')');
3920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
3921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, '-');
3922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (tp == D_PRINT_FLOAT)
3923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, '[');
3924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_comp (dpi, d_right (dc));
3925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (tp == D_PRINT_FLOAT)
3926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, ']');
3927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_RESOURCE:
3931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "java resource ");
3932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPOUND_NAME:
3936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_right (dc));
3938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CHARACTER:
3941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, dc->u.s_character.character);
3942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DECLTYPE:
3945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "decltype (");
3946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (dc));
3947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, ')');
3948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PACK_EXPANSION:
3951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct demangle_component *a = d_find_pack (dpi, d_left (dc));
3953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int len = d_pack_length (a);
3954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int i;
3955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_left (dc);
3957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	for (i = 0; i < len; ++i)
3958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->pack_index = i;
3960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_comp (dpi, dc);
3961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (i < len-1)
3962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_string (dpi, ", ");
3963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
3968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
3969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a Java dentifier.  For Java we try to handle encoded extended
3974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Unicode characters.  The C++ ABI doesn't mention Unicode encoding,
3975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   so we don't it for C++.  Characters are encoded as
3976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __U<hex-char>+_.  */
3977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
3979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_java_identifier (struct d_print_info *dpi, const char *name, int len)
3980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *p;
3982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *end;
3983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  end = name + len;
3985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (p = name; p < end; ++p)
3986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (end - p > 3
3988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && p[0] == '_'
3989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && p[1] == '_'
3990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && p[2] == 'U')
3991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  unsigned long c;
3993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  const char *q;
3994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  c = 0;
3996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  for (q = p + 3; q < end; ++q)
3997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
3998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      int dig;
3999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (IS_DIGIT (*q))
4001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dig = *q - '0';
4002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else if (*q >= 'A' && *q <= 'F')
4003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dig = *q - 'A' + 10;
4004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else if (*q >= 'a' && *q <= 'f')
4005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dig = *q - 'a' + 10;
4006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
4007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
4008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = c * 16 + dig;
4010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* If the Unicode character is larger than 256, we don't try
4012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     to deal with it here.  FIXME.  */
4013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (q < end && *q == '_' && c < 256)
4014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
4015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_char (dpi, c);
4016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      p = q;
4017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      continue;
4018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, *p);
4022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a list of modifiers.  SUFFIX is 1 if we are printing
4026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   qualifiers on this after printing a function.  */
4027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_mod_list (struct d_print_info *dpi,
4030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  struct d_print_mod *mods, int suffix)
4031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_template *hold_dpt;
4033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mods == NULL || d_print_saw_error (dpi))
4035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return;
4036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mods->printed
4038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      || (! suffix
4039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS
4040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS
4041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS)))
4042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_mod_list (dpi, mods->next, suffix);
4044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  mods->printed = 1;
4048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hold_dpt = dpi->templates;
4050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->templates = mods->templates;
4051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mods->mod->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
4053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_function_type (dpi, mods->mod, mods->next);
4055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = hold_dpt;
4056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (mods->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
4059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_array_type (dpi, mods->mod, mods->next);
4061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = hold_dpt;
4062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (mods->mod->type == DEMANGLE_COMPONENT_LOCAL_NAME)
4065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct d_print_mod *hold_modifiers;
4067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *dc;
4068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* When this is on the modifier stack, we have pulled any
4070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 qualifiers off the right argument already.  Otherwise, we
4071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 print it as usual, but don't let the left argument see any
4072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 modifiers.  */
4073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      hold_modifiers = dpi->modifiers;
4075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->modifiers = NULL;
4076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (mods->mod));
4077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->modifiers = hold_modifiers;
4078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((dpi->options & DMGL_JAVA) == 0)
4080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_string (dpi, "::");
4081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
4082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '.');
4083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = d_right (mods->mod);
4085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
4086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
4087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     || dc->type == DEMANGLE_COMPONENT_CONST_THIS)
4088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_left (dc);
4089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, dc);
4091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = hold_dpt;
4093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_print_mod (dpi, mods->mod);
4097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->templates = hold_dpt;
4099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_print_mod_list (dpi, mods->next, suffix);
4101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a modifier.  */
4104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_mod (struct d_print_info *dpi,
4107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             const struct demangle_component *mod)
4108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (mod->type)
4110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT:
4112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
4113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, " restrict");
4114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE:
4116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
4117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, " volatile");
4118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST:
4120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
4121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, " const");
4122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
4124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, ' ');
4125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_right (mod));
4126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_POINTER:
4128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* There is no pointer symbol in Java.  */
4129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((dpi->options & DMGL_JAVA) == 0)
4130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '*');
4131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFERENCE:
4133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '&');
4134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
4136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "&&");
4137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPLEX:
4139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "complex ");
4140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_IMAGINARY:
4142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "imaginary ");
4143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
4145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_last_char (dpi) != '(')
4146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ' ');
4147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (mod));
4148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "::*");
4149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPED_NAME:
4151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (mod));
4152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
4154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Otherwise, we have something that won't go back on the
4155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 modifier stack, so we can just print it.  */
4156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, mod);
4157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a function type, except for the return type.  */
4162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_function_type (struct d_print_info *dpi,
4165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       const struct demangle_component *dc,
4166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       struct d_print_mod *mods)
4167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int need_paren;
4169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int saw_mod;
4170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int need_space;
4171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_mod *p;
4172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_mod *hold_modifiers;
4173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  need_paren = 0;
4175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  saw_mod = 0;
4176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  need_space = 0;
4177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (p = mods; p != NULL; p = p->next)
4178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (p->printed)
4180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	break;
4181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      saw_mod = 1;
4183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (p->mod->type)
4184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_POINTER:
4186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_REFERENCE:
4187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
4188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  need_paren = 1;
4189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_RESTRICT:
4191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_VOLATILE:
4192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_CONST:
4193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
4194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_COMPLEX:
4195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_IMAGINARY:
4196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_PTRMEM_TYPE:
4197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  need_space = 1;
4198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  need_paren = 1;
4199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_RESTRICT_THIS:
4201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_VOLATILE_THIS:
4202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_CONST_THIS:
4203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
4205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (need_paren)
4208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	break;
4209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_left (dc) != NULL && ! saw_mod)
4212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    need_paren = 1;
4213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (need_paren)
4215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! need_space)
4217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (d_last_char (dpi) != '('
4219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      && d_last_char (dpi) != '*')
4220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    need_space = 1;
4221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (need_space && d_last_char (dpi) != ' ')
4223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ' ');
4224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '(');
4225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hold_modifiers = dpi->modifiers;
4228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->modifiers = NULL;
4229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_print_mod_list (dpi, mods, 0);
4231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (need_paren)
4233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, ')');
4234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_char (dpi, '(');
4236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_right (dc) != NULL)
4238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_print_comp (dpi, d_right (dc));
4239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_char (dpi, ')');
4241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_print_mod_list (dpi, mods, 1);
4243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->modifiers = hold_modifiers;
4245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print an array type, except for the element type.  */
4248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_array_type (struct d_print_info *dpi,
4251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    const struct demangle_component *dc,
4252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    struct d_print_mod *mods)
4253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int need_space;
4255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  need_space = 1;
4257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mods != NULL)
4258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int need_paren;
4260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct d_print_mod *p;
4261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      need_paren = 0;
4263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (p = mods; p != NULL; p = p->next)
4264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! p->printed)
4266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
4267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (p->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
4268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
4269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  need_space = 0;
4270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  break;
4271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
4272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
4273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
4274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  need_paren = 1;
4275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  need_space = 1;
4276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  break;
4277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
4278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (need_paren)
4282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_string (dpi, " (");
4283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_mod_list (dpi, mods, 0);
4285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (need_paren)
4287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ')');
4288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (need_space)
4291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, ' ');
4292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_char (dpi, '[');
4294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_left (dc) != NULL)
4296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_print_comp (dpi, d_left (dc));
4297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_char (dpi, ']');
4299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print an operator in an expression.  */
4302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_expr_op (struct d_print_info *dpi,
4305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct demangle_component *dc)
4306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc->type == DEMANGLE_COMPONENT_OPERATOR)
4308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_buffer (dpi, dc->u.s_operator.op->name,
4309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		     dc->u.s_operator.op->len);
4310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
4311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_print_comp (dpi, dc);
4312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a cast.  */
4315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_cast (struct d_print_info *dpi,
4318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              const struct demangle_component *dc)
4319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE)
4321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_print_comp (dpi, d_left (dc));
4322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
4323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct d_print_mod *hold_dpm;
4325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct d_print_template dpt;
4326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* It appears that for a templated cast operator, we need to put
4328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 the template parameters in scope for the operator name, but
4329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 not for the parameters.  The effect is that we need to handle
4330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 the template printing here.  */
4331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      hold_dpm = dpi->modifiers;
4333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->modifiers = NULL;
4334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpt.next = dpi->templates;
4336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = &dpt;
4337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpt.template_decl = d_left (dc);
4338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_left (d_left (dc)));
4340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = dpt.next;
4342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_last_char (dpi) == '<')
4344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ' ');
4345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '<');
4346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_comp (dpi, d_right (d_left (dc)));
4347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Avoid generating two consecutive '>' characters, to avoid
4348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 the C++ syntactic ambiguity.  */
4349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_last_char (dpi) == '>')
4350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ' ');
4351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '>');
4352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->modifiers = hold_dpm;
4354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialize the information structure we use to pass around
4358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   information.  */
4359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
4361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid
4362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_init_info (const char *mangled, int options, size_t len,
4363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct d_info *di)
4364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->s = mangled;
4366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->send = mangled + len;
4367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->options = options;
4368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->n = mangled;
4370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* We can not need more components than twice the number of chars in
4372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     the mangled string.  Most components correspond directly to
4373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     chars, but the ARGLIST types are exceptions.  */
4374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->num_comps = 2 * len;
4375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->next_comp = 0;
4376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Similarly, we can not need more substitutions than there are
4378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     chars in the mangled string.  */
4379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->num_subs = len;
4380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->next_sub = 0;
4381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->did_subs = 0;
4382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->last_name = NULL;
4384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->expansion = 0;
4386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Internal implementation for the demangler.  If MANGLED is a g++ v3 ABI
4389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mangled name, return strings in repeated callback giving the demangled
4390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name.  OPTIONS is the usual libiberty demangler options.  On success,
4391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this returns 1.  On failure, returns 0.  */
4392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
4394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_demangle_callback (const char *mangled, int options,
4395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     demangle_callbackref callback, void *opaque)
4396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int type;
4398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_info di;
4399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *dc;
4400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int status;
4401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mangled[0] == '_' && mangled[1] == 'Z')
4403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    type = 0;
4404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (strncmp (mangled, "_GLOBAL_", 8) == 0
4405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   && (mangled[8] == '.' || mangled[8] == '_' || mangled[8] == '$')
4406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   && (mangled[9] == 'D' || mangled[9] == 'I')
4407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   && mangled[10] == '_')
4408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const char *intro;
4410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      intro = (mangled[9] == 'I')
4412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              ? "global constructors keyed to "
4413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              : "global destructors keyed to ";
4414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      callback (intro, strlen (intro), opaque);
4416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      callback (mangled + 11, strlen (mangled + 11), opaque);
4417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 1;
4418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
4420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((options & DMGL_TYPES) == 0)
4422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return 0;
4423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      type = 1;
4424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  cplus_demangle_init_info (mangled, options, strlen (mangled), &di);
4427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  {
4429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef CP_DYNAMIC_ARRAYS
4430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __extension__ struct demangle_component comps[di.num_comps];
4431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __extension__ struct demangle_component *subs[di.num_subs];
4432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.comps = comps;
4434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.subs = subs;
4435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
4436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.comps = alloca (di.num_comps * sizeof (*di.comps));
4437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.subs = alloca (di.num_subs * sizeof (*di.subs));
4438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (type)
4441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = cplus_demangle_type (&di);
4442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    else
4443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = cplus_demangle_mangled_name (&di, 1);
4444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    /* If DMGL_PARAMS is set, then if we didn't consume the entire
4446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       mangled string, then we didn't successfully demangle it.  If
4447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       DMGL_PARAMS is not set, we didn't look at the trailing
4448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       parameters.  */
4449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (((options & DMGL_PARAMS) != 0) && d_peek_char (&di) != '\0')
4450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = NULL;
4451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef CP_DEMANGLE_DEBUG
4453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_dump (dc, 0);
4454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    status = (dc != NULL)
4457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             ? cplus_demangle_print_callback (options, dc, callback, opaque)
4458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             : 0;
4459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
4460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return status;
4462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Entry point for the demangler.  If MANGLED is a g++ v3 ABI mangled
4465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name, return a buffer allocated with malloc holding the demangled
4466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name.  OPTIONS is the usual libiberty demangler options.  On
4467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   success, this sets *PALC to the allocated size of the returned
4468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   buffer.  On failure, this sets *PALC to 0 for a bad name, or 1 for
4469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a memory allocation failure, and returns NULL.  */
4470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic char *
4472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_demangle (const char *mangled, int options, size_t *palc)
4473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_growable_string dgs;
4475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int status;
4476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_growable_string_init (&dgs, 0);
4478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  status = d_demangle_callback (mangled, options,
4480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                d_growable_string_callback_adapter, &dgs);
4481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (status == 0)
4482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      free (dgs.buf);
4484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *palc = 0;
4485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
4486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *palc = dgs.allocation_failure ? 1 : 0;
4489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dgs.buf;
4490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
4493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern char *__cxa_demangle (const char *, char *, size_t *, int *);
4495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ia64 ABI-mandated entry point in the C++ runtime library for
4497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   performing demangling.  MANGLED_NAME is a NUL-terminated character
4498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   string containing the name to be demangled.
4499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OUTPUT_BUFFER is a region of memory, allocated with malloc, of
4501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *LENGTH bytes, into which the demangled name is stored.  If
4502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OUTPUT_BUFFER is not long enough, it is expanded using realloc.
4503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
4504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   is placed in a region of memory allocated with malloc.
4505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   If LENGTH is non-NULL, the length of the buffer containing the
4507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   demangled name, is placed in *LENGTH.
4508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The return value is a pointer to the start of the NUL-terminated
4510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   demangled name, or NULL if the demangling fails.  The caller is
4511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   responsible for deallocating this memory using free.
4512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *STATUS is set to one of the following values:
4514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      0: The demangling operation succeeded.
4515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -1: A memory allocation failure occurred.
4516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
4517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -3: One of the arguments is invalid.
4518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The demangling is performed using the C++ ABI mangling rules, with
4520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GNU extensions.  */
4521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar *
4523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__cxa_demangle (const char *mangled_name, char *output_buffer,
4524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                size_t *length, int *status)
4525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char *demangled;
4527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t alc;
4528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mangled_name == NULL)
4530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (status != NULL)
4532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	*status = -3;
4533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
4534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (output_buffer != NULL && length == NULL)
4537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (status != NULL)
4539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	*status = -3;
4540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
4541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc);
4544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (demangled == NULL)
4546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (status != NULL)
4548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (alc == 1)
4550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    *status = -1;
4551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  else
4552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    *status = -2;
4553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
4555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (output_buffer == NULL)
4558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (length != NULL)
4560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	*length = alc;
4561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
4563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (strlen (demangled) < *length)
4565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  strcpy (output_buffer, demangled);
4567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  free (demangled);
4568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  demangled = output_buffer;
4569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
4571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  free (output_buffer);
4573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  *length = alc;
4574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (status != NULL)
4578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    *status = 0;
4579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return demangled;
4581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern int __gcclibcxx_demangle_callback (const char *,
4584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                          void (*)
4585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                            (const char *, size_t, void *),
4586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                          void *);
4587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Alternative, allocationless entry point in the C++ runtime library
4589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for performing demangling.  MANGLED_NAME is a NUL-terminated character
4590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   string containing the name to be demangled.
4591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CALLBACK is a callback function, called with demangled string
4593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   segments as demangling progresses; it is called at least once,
4594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   but may be called more than once.  OPAQUE is a generalized pointer
4595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   used as a callback argument.
4596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The return code is one of the following values, equivalent to
4598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the STATUS values of __cxa_demangle() (excluding -1, since this
4599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   function performs no memory allocations):
4600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      0: The demangling operation succeeded.
4601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
4602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -3: One of the arguments is invalid.
4603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The demangling is performed using the C++ ABI mangling rules, with
4605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GNU extensions.  */
4606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
4608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__gcclibcxx_demangle_callback (const char *mangled_name,
4609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               void (*callback) (const char *, size_t, void *),
4610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               void *opaque)
4611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int status;
4613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mangled_name == NULL || callback == NULL)
4615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return -3;
4616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  status = d_demangle_callback (mangled_name, DMGL_PARAMS | DMGL_TYPES,
4618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                callback, opaque);
4619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (status == 0)
4620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return -2;
4621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 0;
4623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
4626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Entry point for libiberty demangler.  If MANGLED is a g++ v3 ABI
4628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mangled name, return a buffer allocated with malloc holding the
4629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   demangled name.  Otherwise, return NULL.  */
4630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar *
4632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_v3 (const char *mangled, int options)
4633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t alc;
4635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_demangle (mangled, options, &alc);
4637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
4640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_v3_callback (const char *mangled, int options,
4641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            demangle_callbackref callback, void *opaque)
4642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_demangle_callback (mangled, options, callback, opaque);
4644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Demangle a Java symbol.  Java uses a subset of the V3 ABI C++ mangling
4647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   conventions, but the output formatting is a little different.
4648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This instructs the C++ demangler not to emit pointer characters ("*"), to
4649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   use Java's namespace separator symbol ("." instead of "::"), and to output
4650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   JArray<TYPE> as TYPE[].  */
4651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar *
4653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownjava_demangle_v3 (const char *mangled)
4654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t alc;
4656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_demangle (mangled, DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX, &alc);
4658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
4661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownjava_demangle_v3_callback (const char *mangled,
4662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           demangle_callbackref callback, void *opaque)
4663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_demangle_callback (mangled,
4665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX,
4666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              callback, opaque);
4667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
4670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef IN_GLIBCPP_V3
4672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Demangle a string in order to find out whether it is a constructor
4674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   or destructor.  Return non-zero on success.  Set *CTOR_KIND and
4675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *DTOR_KIND appropriately.  */
4676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
4678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_ctor_or_dtor (const char *mangled,
4679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 enum gnu_v3_ctor_kinds *ctor_kind,
4680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 enum gnu_v3_dtor_kinds *dtor_kind)
4681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_info di;
4683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *dc;
4684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int ret;
4685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *ctor_kind = (enum gnu_v3_ctor_kinds) 0;
4687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *dtor_kind = (enum gnu_v3_dtor_kinds) 0;
4688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  cplus_demangle_init_info (mangled, DMGL_GNU_V3, strlen (mangled), &di);
4690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  {
4692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef CP_DYNAMIC_ARRAYS
4693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __extension__ struct demangle_component comps[di.num_comps];
4694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __extension__ struct demangle_component *subs[di.num_subs];
4695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.comps = comps;
4697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.subs = subs;
4698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
4699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.comps = alloca (di.num_comps * sizeof (*di.comps));
4700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.subs = alloca (di.num_subs * sizeof (*di.subs));
4701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    dc = cplus_demangle_mangled_name (&di, 1);
4704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    /* Note that because we did not pass DMGL_PARAMS, we don't expect
4706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       to demangle the entire string.  */
4707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ret = 0;
4709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    while (dc != NULL)
4710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
4711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	switch (dc->type)
4712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
4713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  default:
4714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = NULL;
4715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
4716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_TYPED_NAME:
4717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_TEMPLATE:
4718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_RESTRICT_THIS:
4719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_VOLATILE_THIS:
4720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_CONST_THIS:
4721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_left (dc);
4722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
4723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_QUAL_NAME:
4724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_LOCAL_NAME:
4725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_right (dc);
4726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
4727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_CTOR:
4728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    *ctor_kind = dc->u.s_ctor.kind;
4729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = 1;
4730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = NULL;
4731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
4732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_DTOR:
4733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    *dtor_kind = dc->u.s_dtor.kind;
4734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = 1;
4735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = NULL;
4736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
4737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
4738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
4740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
4742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return whether NAME is the mangled form of a g++ V3 ABI constructor
4745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name.  A non-zero return indicates the type of constructor.  */
4746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownenum gnu_v3_ctor_kinds
4748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_gnu_v3_mangled_ctor (const char *name)
4749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  enum gnu_v3_ctor_kinds ctor_kind;
4751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  enum gnu_v3_dtor_kinds dtor_kind;
4752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
4754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return (enum gnu_v3_ctor_kinds) 0;
4755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ctor_kind;
4756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return whether NAME is the mangled form of a g++ V3 ABI destructor
4760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name.  A non-zero return indicates the type of destructor.  */
4761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownenum gnu_v3_dtor_kinds
4763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_gnu_v3_mangled_dtor (const char *name)
4764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  enum gnu_v3_ctor_kinds ctor_kind;
4766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  enum gnu_v3_dtor_kinds dtor_kind;
4767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
4769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return (enum gnu_v3_dtor_kinds) 0;
4770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dtor_kind;
4771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* IN_GLIBCPP_V3 */
4774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef STANDALONE_DEMANGLER
4776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */
4778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "getopt.h"
4779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "dyn-string.h"
4780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */
4781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void print_usage (FILE* fp, int exit_value);
4783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define IS_ALPHA(CHAR)                                                  \
4785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  (((CHAR) >= 'a' && (CHAR) <= 'z')                                     \
4786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
4787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Non-zero if CHAR is a character than can occur in a mangled name.  */
4789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define is_mangled_char(CHAR)                                           \
4790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  (IS_ALPHA (CHAR) || IS_DIGIT (CHAR)                                   \
4791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
4792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The name of this program, as invoked.  */
4794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst char* program_name;
4795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Prints usage summary to FP and then exits with EXIT_VALUE.  */
4797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint_usage (FILE* fp, int exit_value)
4800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
4802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "Options:\n");
4803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "  -h,--help       Display this message.\n");
4804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "  -p,--no-params  Don't display function parameters\n");
4805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "  -v,--verbose    Produce verbose demanglings.\n");
4806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "If names are provided, they are demangled.  Otherwise filters standard input.\n");
4807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  exit (exit_value);
4809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Option specification for getopt_long.  */
4812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const struct option long_options[] =
4813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "help",	 no_argument, NULL, 'h' },
4815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "no-params", no_argument, NULL, 'p' },
4816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "verbose",   no_argument, NULL, 'v' },
4817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { NULL,        no_argument, NULL, 0   },
4818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
4819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Main entry for a demangling filter executable.  It will demangle
4821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   its command line arguments, if any.  If none are provided, it will
4822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   filter stdin to stdout, replacing any recognized mangled C++ names
4823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   with their demangled equivalents.  */
4824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
4826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmain (int argc, char *argv[])
4827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int i;
4829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int opt_char;
4830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int options = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES;
4831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Use the program name of this program, as invoked.  */
4833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  program_name = argv[0];
4834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Parse options.  */
4836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  do
4837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      opt_char = getopt_long (argc, argv, "hpv", long_options, NULL);
4839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (opt_char)
4840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case '?':  /* Unrecognized option.  */
4842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  print_usage (stderr, 1);
4843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'h':
4846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  print_usage (stdout, 0);
4847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'p':
4850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  options &= ~ DMGL_PARAMS;
4851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'v':
4854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  options |= DMGL_VERBOSE;
4855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (opt_char != -1);
4859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (optind == argc)
4861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    /* No command line arguments were provided.  Filter stdin.  */
4862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dyn_string_t mangled = dyn_string_new (3);
4864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      char *s;
4865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read all of input.  */
4867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (!feof (stdin))
4868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  char c;
4870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* Pile characters into mangled until we hit one that can't
4872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     occur in a mangled name.  */
4873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  c = getchar ();
4874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  while (!feof (stdin) && is_mangled_char (c))
4875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
4876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dyn_string_append_char (mangled, c);
4877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (feof (stdin))
4878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
4879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = getchar ();
4880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (dyn_string_length (mangled) > 0)
4883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
4884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef IN_GLIBCPP_V3
4885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      s = __cxa_demangle (dyn_string_buf (mangled), NULL, NULL, NULL);
4886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
4887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      s = cplus_demangle_v3 (dyn_string_buf (mangled), options);
4888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (s != NULL)
4891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
4892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  fputs (s, stdout);
4893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  free (s);
4894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
4895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
4896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
4897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  /* It might not have been a mangled name.  Print the
4898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		     original text.  */
4899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  fputs (dyn_string_buf (mangled), stdout);
4900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
4901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dyn_string_clear (mangled);
4903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* If we haven't hit EOF yet, we've read one character that
4906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     can't occur in a mangled name, so print it out.  */
4907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (!feof (stdin))
4908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    putchar (c);
4909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dyn_string_delete (mangled);
4912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
4914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    /* Demangle command line arguments.  */
4915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Loop over command line arguments.  */
4917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = optind; i < argc; ++i)
4918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  char *s;
4920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef IN_GLIBCPP_V3
4921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  int status;
4922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* Attempt to demangle.  */
4925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef IN_GLIBCPP_V3
4926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  s = __cxa_demangle (argv[i], NULL, NULL, &status);
4927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
4928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  s = cplus_demangle_v3 (argv[i], options);
4929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* If it worked, print the demangled name.  */
4932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (s != NULL)
4933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
4934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      printf ("%s\n", s);
4935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      free (s);
4936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  else
4938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
4939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef IN_GLIBCPP_V3
4940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      fprintf (stderr, "Failed: %s (status %d)\n", argv[i], status);
4941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
4942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      fprintf (stderr, "Failed: %s\n", argv[i]);
4943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 0;
4949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* STANDALONE_DEMANGLER */
4952