1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Demangler for g++ V3 ABI.
2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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  /* Fixed-length allocated buffer for demangled data, flushed to the
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     callback with a NUL termination once full.  */
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char buf[D_PRINT_BUFFER_LENGTH];
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Current length of data in buffer.  */
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t len;
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The last character printed, saved individually so that it survives
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     any buffer flush.  */
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char last_char;
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Callback function to handle demangled buffer flush.  */
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  demangle_callbackref callback;
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Opaque callback argument.  */
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  void *opaque;
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The current list of templates, if any.  */
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_template *templates;
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The current list of modifiers (e.g., pointer, reference, etc.),
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     if any.  */
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_mod *modifiers;
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Set to 1 if we saw a demangling error.  */
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int demangle_failure;
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The current index into any template argument packs we are using
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     for printing.  */
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int pack_index;
318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  /* Number of d_print_flush calls so far.  */
319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  unsigned long int flush_count;
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 *
338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_make_demangle_mangled_name (struct d_info *, const char *);
339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_builtin_type (struct d_info *,
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     const struct demangle_builtin_type_info *);
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_operator (struct d_info *,
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct demangle_operator_info *);
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_extended_operator (struct d_info *, int,
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct demangle_component *);
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_ctor (struct d_info *, enum gnu_v3_ctor_kinds,
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *);
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_dtor (struct d_info *, enum gnu_v3_dtor_kinds,
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *);
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_template_param (struct d_info *, long);
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_sub (struct d_info *, const char *, int);
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownhas_return_type (struct demangle_component *);
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_ctor_dtor_or_conversion (struct demangle_component *);
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_encoding (struct d_info *, int);
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_name (struct d_info *);
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_nested_name (struct d_info *);
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_prefix (struct d_info *);
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_unqualified_name (struct d_info *);
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_source_name (struct d_info *);
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic long d_number (struct d_info *);
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_identifier (struct d_info *, int);
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_operator_name (struct d_info *);
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_special_name (struct d_info *);
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int d_call_offset (struct d_info *, int);
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_ctor_dtor_name (struct d_info *);
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component **
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_cv_qualifiers (struct d_info *, struct demangle_component **, int);
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_function_type (struct d_info *);
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_bare_function_type (struct d_info *, int);
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_class_enum_type (struct d_info *);
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_array_type (struct d_info *);
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *d_vector_type (struct d_info *);
411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_pointer_to_member_type (struct d_info *);
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_param (struct d_info *);
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_template_args (struct d_info *);
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_arg (struct d_info *);
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_expression (struct d_info *);
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_expr_primary (struct d_info *);
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_local_name (struct d_info *);
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int d_discriminator (struct d_info *);
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *d_lambda (struct d_info *);
432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *d_unnamed_type (struct d_info *);
434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_clone_suffix (struct d_info *, struct demangle_component *);
437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_add_substitution (struct d_info *, struct demangle_component *);
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *d_substitution (struct d_info *, int);
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void d_growable_string_init (struct d_growable_string *, size_t);
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_resize (struct d_growable_string *, size_t);
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_append_buffer (struct d_growable_string *,
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 const char *, size_t);
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_callback_adapter (const char *, size_t, void *);
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_init (struct d_print_info *, demangle_callbackref, void *);
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_print_error (struct d_print_info *);
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline int d_print_saw_error (struct d_print_info *);
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_print_flush (struct d_print_info *);
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_append_char (struct d_print_info *, char);
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_append_buffer (struct d_print_info *,
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    const char *, size_t);
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void d_append_string (struct d_print_info *, const char *);
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline char d_last_char (struct d_print_info *);
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_comp (struct d_print_info *, int, const struct demangle_component *);
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_java_identifier (struct d_print_info *, const char *, int);
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_mod_list (struct d_print_info *, int, struct d_print_mod *, int);
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_mod (struct d_print_info *, int, const struct demangle_component *);
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_function_type (struct d_print_info *, int,
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       const struct demangle_component *,
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       struct d_print_mod *);
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_array_type (struct d_print_info *, int,
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    const struct demangle_component *,
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    struct d_print_mod *);
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_expr_op (struct d_print_info *, int, const struct demangle_component *);
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_cast (struct d_print_info *, int, const struct demangle_component *);
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int d_demangle_callback (const char *, int,
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                demangle_callbackref, void *);
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic char *d_demangle (const char *, int, size_t *);
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef CP_DEMANGLE_DEBUG
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_dump (struct demangle_component *dc, int indent)
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int i;
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (indent == 0)
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        printf ("failed demangling\n");
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (i = 0; i < indent; ++i)
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    putchar (' ');
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_NAME:
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("name '%.*s'\n", dc->u.s_name.len, dc->u.s_name.s);
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("template parameter %ld\n", dc->u.s_number.number);
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CTOR:
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("constructor %d\n", (int) dc->u.s_ctor.kind);
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_dump (dc->u.s_ctor.name, indent + 2);
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DTOR:
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("destructor %d\n", (int) dc->u.s_dtor.kind);
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_dump (dc->u.s_dtor.name, indent + 2);
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_SUB_STD:
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("standard substitution %s\n", dc->u.s_string.string);
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("builtin type %s\n", dc->u.s_builtin.type->name);
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_OPERATOR:
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("operator %s\n", dc->u.s_operator.op->name);
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("extended operator with %d args\n",
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dc->u.s_extended_operator.args);
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_dump (dc->u.s_extended_operator.name, indent + 2);
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_QUAL_NAME:
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("qualified name\n");
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LOCAL_NAME:
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("local name\n");
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPED_NAME:
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("typed name\n");
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE:
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("template\n");
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTABLE:
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("vtable\n");
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTT:
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("VTT\n");
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("construction vtable\n");
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO:
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("typeinfo\n");
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_NAME:
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("typeinfo name\n");
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_FN:
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("typeinfo function\n");
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_THUNK:
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("thunk\n");
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("virtual thunk\n");
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COVARIANT_THUNK:
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("covariant thunk\n");
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_CLASS:
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("java class\n");
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_GUARD:
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("guard\n");
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFTEMP:
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("reference temporary\n");
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("hidden alias\n");
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
604663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf ("transaction clone\n");
605663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      break;
606663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
607663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf ("non-transaction clone\n");
608663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      break;
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT:
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("restrict\n");
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE:
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("volatile\n");
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST:
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("const\n");
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("restrict this\n");
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("volatile this\n");
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("const this\n");
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("vendor type qualifier\n");
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_POINTER:
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("pointer\n");
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFERENCE:
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("reference\n");
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("rvalue reference\n");
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPLEX:
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("complex\n");
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_IMAGINARY:
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("imaginary\n");
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE:
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("vendor type\n");
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("function type\n");
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARRAY_TYPE:
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("array type\n");
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("pointer to member type\n");
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_FIXED_TYPE:
658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf ("fixed-point type\n");
659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      break;
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARGLIST:
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("argument list\n");
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("template argument list\n");
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CAST:
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("cast\n");
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_UNARY:
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("unary operator\n");
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY:
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("binary operator\n");
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY_ARGS:
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("binary operator arguments\n");
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY:
679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("trinary operator\n");
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG1:
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("trinary operator arguments 1\n");
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG2:
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("trinary operator arguments 1\n");
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL:
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("literal\n");
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL_NEG:
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("negative literal\n");
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_RESOURCE:
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("java resource\n");
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPOUND_NAME:
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("compound name\n");
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CHARACTER:
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("character '%c'\n",  dc->u.s_character.character);
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DECLTYPE:
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("decltype\n");
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PACK_EXPANSION:
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      printf ("pack expansion\n");
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_dump (d_left (dc), indent + 2);
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_dump (d_right (dc), indent + 2);
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* CP_DEMANGLE_DEBUG */
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Fill in a DEMANGLE_COMPONENT_NAME.  */
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_fill_name (struct demangle_component *p, const char *s, int len)
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p == NULL || s == NULL || len == 0)
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->type = DEMANGLE_COMPONENT_NAME;
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_name.s = s;
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_name.len = len;
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR.  */
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_fill_extended_operator (struct demangle_component *p, int args,
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                       struct demangle_component *name)
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p == NULL || args < 0 || name == NULL)
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_extended_operator.args = args;
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_extended_operator.name = name;
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Fill in a DEMANGLE_COMPONENT_CTOR.  */
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_fill_ctor (struct demangle_component *p,
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          enum gnu_v3_ctor_kinds kind,
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct demangle_component *name)
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p == NULL
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      || name == NULL
755663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      || (int) kind < gnu_v3_complete_object_ctor
756663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      || (int) kind > gnu_v3_object_ctor_group)
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->type = DEMANGLE_COMPONENT_CTOR;
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_ctor.kind = kind;
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_ctor.name = name;
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Fill in a DEMANGLE_COMPONENT_DTOR.  */
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_fill_dtor (struct demangle_component *p,
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          enum gnu_v3_dtor_kinds kind,
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct demangle_component *name)
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p == NULL
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      || name == NULL
774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      || (int) kind < gnu_v3_deleting_dtor
775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      || (int) kind > gnu_v3_object_dtor_group)
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->type = DEMANGLE_COMPONENT_DTOR;
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_dtor.kind = kind;
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p->u.s_dtor.name = name;
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new component.  */
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_empty (struct d_info *di)
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (di->next_comp >= di->num_comps)
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = &di->comps[di->next_comp];
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ++di->next_comp;
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new generic component.  */
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_comp (struct d_info *di, enum demangle_component_type type,
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *left,
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *right)
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* We check for errors here.  A typical error would be a NULL return
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     from a subroutine.  We catch those here, and return NULL
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     upward.  */
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (type)
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These types require two parameters.  */
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_QUAL_NAME:
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LOCAL_NAME:
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPED_NAME:
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE:
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_UNARY:
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY:
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY_ARGS:
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY:
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG1:
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG2:
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL:
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL_NEG:
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPOUND_NAME:
828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_VECTOR_TYPE:
829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_CLONE:
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (left == NULL || right == NULL)
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These types only require one parameter.  */
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTABLE:
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTT:
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO:
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_NAME:
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_FN:
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_THUNK:
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COVARIANT_THUNK:
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_CLASS:
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_GUARD:
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFTEMP:
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_POINTER:
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFERENCE:
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPLEX:
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_IMAGINARY:
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE:
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CAST:
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_RESOURCE:
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DECLTYPE:
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PACK_EXPANSION:
859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (left == NULL)
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* This needs a right parameter, but the left parameter can be
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 empty.  */
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARRAY_TYPE:
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (right == NULL)
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These are allowed to have no parameters--in some cases they
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 will be filled in later.  */
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT:
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE:
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST:
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARGLIST:
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Other types should not be seen here.  */
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = type;
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_binary.left = left;
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_binary.right = right;
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Add a new demangle mangled name component.  */
901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
903663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_make_demangle_mangled_name (struct d_info *di, const char *s)
904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (d_peek_char (di) != '_' || d_peek_next_char (di) != 'Z')
906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return d_make_name (di, s, strlen (s));
907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_advance (di, 2);
908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return d_encoding (di, 0);
909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new name component.  */
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_name (struct d_info *di, const char *s, int len)
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_fill_name (p, s, len))
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new builtin type component.  */
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_builtin_type (struct d_info *di,
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     const struct demangle_builtin_type_info *type)
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (type == NULL)
933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE;
938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_builtin.type = type;
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new operator component.  */
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_operator (struct d_info *di, const struct demangle_operator_info *op)
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_OPERATOR;
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_operator.op = op;
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new extended operator component.  */
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_extended_operator (struct d_info *di, int args,
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct demangle_component *name)
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_fill_extended_operator (p, args, name))
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_make_default_arg (struct d_info *di, int num,
975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		    struct demangle_component *sub)
976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *p = d_make_empty (di);
978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (p)
979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p->type = DEMANGLE_COMPONENT_DEFAULT_ARG;
981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p->u.s_unary_num.num = num;
982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p->u.s_unary_num.sub = sub;
983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return p;
985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new constructor component.  */
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_ctor (struct d_info *di, enum gnu_v3_ctor_kinds kind,
991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *name)
992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_fill_ctor (p, kind, name))
997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new destructor component.  */
1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_dtor (struct d_info *di, enum gnu_v3_dtor_kinds kind,
1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             struct demangle_component *name)
1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_fill_dtor (p, kind, name))
1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new template parameter.  */
1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_template_param (struct d_info *di, long i)
1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_TEMPLATE_PARAM;
1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_number.number = i;
1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Add a new function parameter.  */
1032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
1034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_make_function_param (struct d_info *di, long i)
1035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
1036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *p;
1037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  p = d_make_empty (di);
1039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (p != NULL)
1040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
1041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p->type = DEMANGLE_COMPONENT_FUNCTION_PARAM;
1042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p->u.s_number.number = i;
1043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
1044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return p;
1045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new standard substitution component.  */
1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_sub (struct d_info *di, const char *name, int len)
1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_SUB_STD;
1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_string.string = name;
1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_string.len = len;
1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TOP_LEVEL is non-zero when called at the top level.  */
1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct demangle_component *
1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_mangled_name (struct d_info *di, int top_level)
1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *p;
1073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_check_char (di, '_')
1075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Allow missing _ if not at toplevel to work around a
1076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	 bug in G++ abi-version=2 mangling; see the comment in
1077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	 write_template_arg.  */
1078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      && top_level)
1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'Z'))
1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  p = d_encoding (di, top_level);
1083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  /* If at top level and parsing parameters, check for a clone
1085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng     suffix.  */
1086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (top_level && (di->options & DMGL_PARAMS) != 0)
1087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    while (d_peek_char (di) == '.'
1088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	   && (IS_LOWER (d_peek_next_char (di))
1089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       || d_peek_next_char (di) == '_'
1090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       || IS_DIGIT (d_peek_next_char (di))))
1091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      p = d_clone_suffix (di, p);
1092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return p;
1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return whether a function should have a return type.  The argument
1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   is the function name, which may be qualified in various ways.  The
1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   rules are that template functions have return types with some
1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   exceptions, function types which are not part of a function name
1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mangling have return types with some exceptions, and non-template
1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   function names do not have return types.  The exceptions are that
1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   constructors, destructors, and conversion operators do not have
1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return types.  */
1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownhas_return_type (struct demangle_component *dc)
1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 0;
1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE:
1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ! is_ctor_dtor_or_conversion (d_left (dc));
1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return has_return_type (d_left (dc));
1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return whether a name is a constructor, a destructor, or a
1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   conversion operator.  */
1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_ctor_dtor_or_conversion (struct demangle_component *dc)
1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 0;
1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_QUAL_NAME:
1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LOCAL_NAME:
1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return is_ctor_dtor_or_conversion (d_right (dc));
1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CTOR:
1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DTOR:
1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CAST:
1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 1;
1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <encoding> ::= <(function) name> <bare-function-type>
1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              ::= <(data) name>
1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              ::= <special-name>
1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TOP_LEVEL is non-zero when called at the top level, in which case
1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if DMGL_PARAMS is not set we do not demangle the function
1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parameters.  We only set this at the top level, because otherwise
1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   we would not correctly demangle names in local scopes.  */
1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_encoding (struct d_info *di, int top_level)
1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek = d_peek_char (di);
1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == 'G' || peek == 'T')
1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_special_name (di);
1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *dc;
1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = d_name (di);
1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dc != NULL && top_level && (di->options & DMGL_PARAMS) == 0)
1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* Strip off any initial CV-qualifiers, as they really apply
1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     to the `this' parameter, and they were not output by the
1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     v2 demangler without DMGL_PARAMS.  */
1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		 || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		 || dc->type == DEMANGLE_COMPONENT_CONST_THIS)
1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_left (dc);
1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then
1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     there may be CV-qualifiers on its right argument which
1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     really apply here; this happens when parsing a class
1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     which is local to a function.  */
1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      struct demangle_component *dcr;
1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dcr = d_right (dc);
1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS
1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		     || dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS
1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		     || dcr->type == DEMANGLE_COMPONENT_CONST_THIS)
1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dcr = d_left (dcr);
1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dc->u.s_binary.right = dcr;
1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return dc;
1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dc == NULL || peek == '\0' || peek == 'E')
1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return dc;
1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc,
1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			  d_bare_function_type (di, has_return_type (dc)));
1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <name> ::= <nested-name>
1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <unscoped-name>
1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <unscoped-template-name> <template-args>
1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <local-name>
1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <unscoped-name> ::= <unqualified-name>
1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   ::= St <unqualified-name>
1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <unscoped-template-name> ::= <unscoped-name>
1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            ::= <substitution>
1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_name (struct d_info *di)
1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek = d_peek_char (di);
1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *dc;
1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (peek)
1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'N':
1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_nested_name (di);
1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'Z':
1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_local_name (di);
1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'L':
1231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case 'U':
1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_unqualified_name (di);
1233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'S':
1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int subst;
1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (d_peek_next_char (di) != 't')
1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_substitution (di, 0);
1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    subst = 1;
1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	else
1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_advance (di, 2);
1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME,
1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_make_name (di, "std", 3),
1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_unqualified_name (di));
1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    di->expansion += 3;
1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    subst = 0;
1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (d_peek_char (di) != 'I')
1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* The grammar does not permit this case to occur if we
1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       called d_substitution() above (i.e., subst == 1).  We
1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       don't bother to check.  */
1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	else
1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* This is <template-args>, which means that we just saw
1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       <unscoped-template-name>, which is a substitution
1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       candidate if we didn't just get it from a
1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       substitution.  */
1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! subst)
1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (! d_add_substitution (di, dc))
1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  return NULL;
1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_template_args (di));
1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return dc;
1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = d_unqualified_name (di);
1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'I')
1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* This is <template-args>, which means that we just saw
1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     <unscoped-template-name>, which is a substitution
1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     candidate.  */
1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_add_substitution (di, dc))
1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    d_template_args (di));
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return dc;
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_nested_name (struct d_info *di)
1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **pret;
1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'N'))
1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pret = d_cv_qualifiers (di, &ret, 1);
1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (pret == NULL)
1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *pret = d_prefix (di);
1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (*pret == NULL)
1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'E'))
1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <prefix> ::= <prefix> <unqualified-name>
1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ::= <template-prefix> <template-args>
1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ::= <template-param>
1323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            ::= <decltype>
1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ::=
1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ::= <substitution>
1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <template-prefix> ::= <prefix> <(template) unqualified-name>
1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ::= <template-param>
1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ::= <substitution>
1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_prefix (struct d_info *di)
1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret = NULL;
1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      char peek;
1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      enum demangle_component_type comb_type;
1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *dc;
1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (peek == '\0')
1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* The older code accepts a <local-name> here, but I don't see
1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 that in the grammar.  The older code does not accept a
1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 <template-param> here.  */
1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      comb_type = DEMANGLE_COMPONENT_QUAL_NAME;
1352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (peek == 'D')
1353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
1354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  char peek2 = d_peek_next_char (di);
1355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if (peek2 == 'T' || peek2 == 't')
1356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    /* Decltype.  */
1357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    dc = cplus_demangle_type (di);
1358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  else
1359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    /* Destructor name.  */
1360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    dc = d_unqualified_name (di);
1361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
1362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      else if (IS_DIGIT (peek)
1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  || IS_LOWER (peek)
1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  || peek == 'C'
1365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  || peek == 'U'
1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  || peek == 'L')
1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_unqualified_name (di);
1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'S')
1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_substitution (di, 1);
1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'I')
1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (ret == NULL)
1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  comb_type = DEMANGLE_COMPONENT_TEMPLATE;
1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  dc = d_template_args (di);
1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'T')
1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_template_param (di);
1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'E')
1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return ret;
1381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      else if (peek == 'M')
1382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
1383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  /* Initializer scope for a lambda.  We don't need to represent
1384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     this; the normal code will just treat the variable as a type
1385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     scope, which gives appropriate output.  */
1386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if (ret == NULL)
1387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    return NULL;
1388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_advance (di, 1);
1389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  continue;
1390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ret == NULL)
1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret = dc;
1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	ret = d_make_comp (di, comb_type, ret, dc);
1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (peek != 'S' && d_peek_char (di) != 'E')
1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_add_substitution (di, ret))
1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <unqualified-name> ::= <operator-name>
1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      ::= <ctor-dtor-name>
1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      ::= <source-name>
1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      ::= <local-source-name>
1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    <local-source-name>	::= L <source-name> <discriminator>
1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_unqualified_name (struct d_info *di)
1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (IS_DIGIT (peek))
1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_source_name (di);
1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (IS_LOWER (peek))
1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *ret;
1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_operator_name (di);
1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion += sizeof "operator" + ret->u.s_operator.op->len - 2;
1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ret;
1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (peek == 'C' || peek == 'D')
1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_ctor_dtor_name (di);
1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (peek == 'L')
1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component * ret;
1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_source_name (di);
1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ret == NULL)
1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_discriminator (di))
1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ret;
1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  else if (peek == 'U')
1448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
1449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      switch (d_peek_next_char (di))
1450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
1451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	case 'l':
1452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  return d_lambda (di);
1453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	case 't':
1454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  return d_unnamed_type (di);
1455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	default:
1456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  return NULL;
1457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
1458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <source-name> ::= <(positive length) number> <identifier>  */
1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_source_name (struct d_info *di)
1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long len;
1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  len = d_number (di);
1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (len <= 0)
1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ret = d_identifier (di, len);
1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->last_name = ret;
1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* number ::= [n] <(non-negative decimal integer)>  */
1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic long
1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_number (struct d_info *di)
1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int negative;
1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long ret;
1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  negative = 0;
1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == 'n')
1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      negative = 1;
1493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
1494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ret = 0;
1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! IS_DIGIT (peek))
1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (negative)
1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = - ret;
1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return ret;
1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = ret * 10 + peek - '0';
1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Like d_number, but returns a demangle_component.  */
1513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
1515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_number_component (struct d_info *di)
1516663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
1517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *ret = d_make_empty (di);
1518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (ret)
1519663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
1520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ret->type = DEMANGLE_COMPONENT_NUMBER;
1521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ret->u.s_number.number = d_number (di);
1522663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
1523663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return ret;
1524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
1525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* identifier ::= <(unqualified source code identifier)>  */
1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_identifier (struct d_info *di, int len)
1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *name;
1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  name = d_str (di);
1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (di->send - name < len)
1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_advance (di, len);
1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* A Java mangled name may have a trailing '$' if it is a C++
1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     keyword.  This '$' is not included in the length count.  We just
1542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     ignore the '$'.  */
1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if ((di->options & DMGL_JAVA) != 0
1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      && d_peek_char (di) == '$')
1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_advance (di, 1);
1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Look for something which looks like a gcc encoding of an
1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     anonymous namespace, and replace it with a more user friendly
1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     name.  */
1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2
1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      && memcmp (name, ANONYMOUS_NAMESPACE_PREFIX,
1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		 ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0)
1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const char *s;
1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      s = name + ANONYMOUS_NAMESPACE_PREFIX_LEN;
1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((*s == '.' || *s == '_' || *s == '$')
1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && s[1] == 'N')
1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion -= len - sizeof "(anonymous namespace)";
1561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_name (di, "(anonymous namespace)",
1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      sizeof "(anonymous namespace)" - 1);
1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_make_name (di, name, len);
1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* operator_name ::= many different two character encodings.
1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 ::= cv <type>
1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 ::= v <digit> <source-name>
1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define NL(s) s, (sizeof s) - 1
1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst struct demangle_operator_info cplus_demangle_operators[] =
1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "aN", NL ("&="),        2 },
1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "aS", NL ("="),         2 },
1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "aa", NL ("&&"),        2 },
1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ad", NL ("&"),         1 },
1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "an", NL ("&"),         2 },
1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "cl", NL ("()"),        2 },
1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "cm", NL (","),         2 },
1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "co", NL ("~"),         1 },
1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "dV", NL ("/="),        2 },
1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "da", NL ("delete[]"),  1 },
1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "de", NL ("*"),         1 },
1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "dl", NL ("delete"),    1 },
1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "dt", NL ("."),         2 },
1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "dv", NL ("/"),         2 },
1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "eO", NL ("^="),        2 },
1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "eo", NL ("^"),         2 },
1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "eq", NL ("=="),        2 },
1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ge", NL (">="),        2 },
1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "gt", NL (">"),         2 },
1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ix", NL ("[]"),        2 },
1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "lS", NL ("<<="),       2 },
1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "le", NL ("<="),        2 },
1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ls", NL ("<<"),        2 },
1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "lt", NL ("<"),         2 },
1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "mI", NL ("-="),        2 },
1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "mL", NL ("*="),        2 },
1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "mi", NL ("-"),         2 },
1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ml", NL ("*"),         2 },
1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "mm", NL ("--"),        1 },
1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "na", NL ("new[]"),     1 },
1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ne", NL ("!="),        2 },
1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ng", NL ("-"),         1 },
1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "nt", NL ("!"),         1 },
1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "nw", NL ("new"),       1 },
1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "oR", NL ("|="),        2 },
1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "oo", NL ("||"),        2 },
1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "or", NL ("|"),         2 },
1616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pL", NL ("+="),        2 },
1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pl", NL ("+"),         2 },
1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pm", NL ("->*"),       2 },
1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pp", NL ("++"),        1 },
1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "ps", NL ("+"),         1 },
1621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "pt", NL ("->"),        2 },
1622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "qu", NL ("?"),         3 },
1623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "rM", NL ("%="),        2 },
1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "rS", NL (">>="),       2 },
1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "rm", NL ("%"),         2 },
1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "rs", NL (">>"),        2 },
1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "st", NL ("sizeof "),   1 },
1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "sz", NL ("sizeof "),   1 },
1629663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  { "at", NL ("alignof "),   1 },
1630663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  { "az", NL ("alignof "),   1 },
1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { NULL, NULL, 0,          0 }
1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_operator_name (struct d_info *di)
1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char c1;
1638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char c2;
1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  c1 = d_next_char (di);
1641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  c2 = d_next_char (di);
1642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (c1 == 'v' && IS_DIGIT (c2))
1643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_make_extended_operator (di, c2 - '0', d_source_name (di));
1644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (c1 == 'c' && c2 == 'v')
1645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_make_comp (di, DEMANGLE_COMPONENT_CAST,
1646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			cplus_demangle_type (di), NULL);
1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* LOW is the inclusive lower bound.  */
1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int low = 0;
1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* HIGH is the exclusive upper bound.  We subtract one to ignore
1652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 the sentinel at the end of the array.  */
1653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int high = ((sizeof (cplus_demangle_operators)
1654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   / sizeof (cplus_demangle_operators[0]))
1655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  - 1);
1656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (1)
1658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  int i;
1660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  const struct demangle_operator_info *p;
1661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  i = low + (high - low) / 2;
1663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  p = cplus_demangle_operators + i;
1664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (c1 == p->code[0] && c2 == p->code[1])
1666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return d_make_operator (di, p);
1667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (c1 < p->code[0] || (c1 == p->code[0] && c2 < p->code[1]))
1669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    high = i;
1670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  else
1671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    low = i + 1;
1672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (low == high)
1673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_make_character (struct d_info *di, int c)
1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p;
1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_empty (di);
1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (p != NULL)
1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->type = DEMANGLE_COMPONENT_CHARACTER;
1686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p->u.s_character.character = c;
1687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_java_resource (struct d_info *di)
1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *p = NULL;
1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *next = NULL;
1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long len, i;
1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char c;
1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *str;
1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  len = d_number (di);
1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (len <= 1)
1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Eat the leading '_'.  */
1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_next_char (di) != '_')
1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  len--;
1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  str = d_str (di);
1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  i = 0;
1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (len > 0)
1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      c = str[i];
1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!c)
1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Each chunk is either a '$' escape...  */
1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (c == '$')
1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  i++;
1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  switch (str[i++])
1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    case 'S':
1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = '/';
1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      break;
1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    case '_':
1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = '.';
1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      break;
1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    case '$':
1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = '$';
1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      break;
1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    default:
1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return NULL;
1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  next = d_make_character (di, c);
1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, i);
1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  str = d_str (di);
1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  len -= i;
1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  i = 0;
1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (next == NULL)
1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... or a sequence of characters.  */
1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  while (i < len && str[i] && str[i] != '$')
1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    i++;
1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  next = d_make_name (di, str, i);
1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, i);
1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  str = d_str (di);
1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  len -= i;
1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  i = 0;
1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (next == NULL)
1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (p == NULL)
1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	p = next;
1761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
1762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  p = d_make_comp (di, DEMANGLE_COMPONENT_COMPOUND_NAME, p, next);
1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (p == NULL)
1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  p = d_make_comp (di, DEMANGLE_COMPONENT_JAVA_RESOURCE, p, NULL);
1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return p;
1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <special-name> ::= TV <type>
1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TT <type>
1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TI <type>
1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TS <type>
1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= GV <(object) name>
1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= T <call-offset> <(base) encoding>
1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Tc <call-offset> <call-offset> <(base) encoding>
1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Also g++ extensions:
1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TC <type> <(offset) number> _ <(base) type>
1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TF <type>
1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= TJ <type>
1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= GR <name>
1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  ::= GA <encoding>
1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  ::= Gr <resource name>
1788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		  ::= GTt <encoding>
1789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		  ::= GTn <encoding>
1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_special_name (struct d_info *di)
1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->expansion += 20;
1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_check_char (di, 'T'))
1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (d_next_char (di))
1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'V':
1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion -= 5;
1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_VTABLE,
1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'T':
1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion -= 10;
1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_VTT,
1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'I':
1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO,
1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'S':
1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_NAME,
1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'h':
1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_call_offset (di, 'h'))
1817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_THUNK,
1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_encoding (di, 0), NULL);
1820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'v':
1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_call_offset (di, 'v'))
1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_VIRTUAL_THUNK,
1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_encoding (di, 0), NULL);
1826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'c':
1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_call_offset (di, '\0'))
1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_call_offset (di, '\0'))
1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_COVARIANT_THUNK,
1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_encoding (di, 0), NULL);
1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'C':
1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *derived_type;
1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    long offset;
1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *base_type;
1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    derived_type = cplus_demangle_type (di);
1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    offset = d_number (di);
1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (offset < 0)
1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return NULL;
1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! d_check_char (di, '_'))
1846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return NULL;
1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    base_type = cplus_demangle_type (di);
1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* We don't display the offset.  FIXME: We should display
1849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       it in verbose mode.  */
1850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    di->expansion += 5;
1851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return d_make_comp (di, DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
1852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				base_type, derived_type);
1853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'F':
1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_FN,
1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'J':
1859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_JAVA_CLASS,
1860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      cplus_demangle_type (di), NULL);
1861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
1863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return NULL;
1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (d_check_char (di, 'G'))
1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (d_next_char (di))
1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'V':
1871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, d_name (di), NULL);
1872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'R':
1874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  {
1875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    struct demangle_component *name = d_name (di);
1876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, name,
1877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng				d_number_component (di));
1878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  }
1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'A':
1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_make_comp (di, DEMANGLE_COMPONENT_HIDDEN_ALIAS,
1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			      d_encoding (di, 0), NULL);
1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	case 'T':
1885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  switch (d_next_char (di))
1886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    {
1887663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    case 'n':
1888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      return d_make_comp (di, DEMANGLE_COMPONENT_NONTRANSACTION_CLONE,
1889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng				  d_encoding (di, 0), NULL);
1890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    default:
1891663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      /* ??? The proposal is that other letters (such as 'h') stand
1892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		 for different variants of transaction cloning, such as
1893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		 compiling directly for hardware transaction support.  But
1894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		 they still should all be transactional clones of some sort
1895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		 so go ahead and call them that.  */
1896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    case 't':
1897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      return d_make_comp (di, DEMANGLE_COMPONENT_TRANSACTION_CLONE,
1898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng				  d_encoding (di, 0), NULL);
1899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    }
1900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'r':
1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return d_java_resource (di);
1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return NULL;
1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <call-offset> ::= h <nv-offset> _
1913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 ::= v <v-offset> _
1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <nv-offset> ::= <(offset) number>
1916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <v-offset> ::= <(offset) number> _ <(virtual offset) number>
1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The C parameter, if not '\0', is a character we just read which is
1920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the start of the <call-offset>.
1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   We don't display the offset information anywhere.  FIXME: We should
1923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   display it in verbose mode.  */
1924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
1926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_call_offset (struct d_info *di, int c)
1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (c == '\0')
1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    c = d_next_char (di);
1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (c == 'h')
1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_number (di);
1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (c == 'v')
1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_number (di);
1936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_check_char (di, '_'))
1937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return 0;
1938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_number (di);
1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
1941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
1942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, '_'))
1944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
1945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
1947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <ctor-dtor-name> ::= C1
1950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= C2
1951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= C3
1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= D0
1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= D1
1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= D2
1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_ctor_dtor_name (struct d_info *di)
1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (di->last_name != NULL)
1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (di->last_name->type == DEMANGLE_COMPONENT_NAME)
1963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion += di->last_name->u.s_name.len;
1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD)
1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion += di->last_name->u.s_string.len;
1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
1967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (d_peek_char (di))
1968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
1969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'C':
1970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	enum gnu_v3_ctor_kinds kind;
1972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	switch (d_peek_next_char (di))
1974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
1975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '1':
1976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_complete_object_ctor;
1977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
1978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '2':
1979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_base_object_ctor;
1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '3':
1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_complete_object_allocating_ctor;
1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
1984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  case '5':
1985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    kind = gnu_v3_object_ctor_group;
1986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    break;
1987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  default:
1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
1990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_advance (di, 2);
1991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_ctor (di, kind, di->last_name);
1992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'D':
1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	enum gnu_v3_dtor_kinds kind;
1997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	switch (d_peek_next_char (di))
1999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
2000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '0':
2001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_deleting_dtor;
2002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
2003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '1':
2004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_complete_object_dtor;
2005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
2006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case '2':
2007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    kind = gnu_v3_base_object_dtor;
2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
2009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  case '5':
2010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    kind = gnu_v3_object_dtor_group;
2011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    break;
2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  default:
2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_advance (di, 2);
2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_dtor (di, kind, di->last_name);
2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <type> ::= <builtin-type>
2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <function-type>
2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <class-enum-type>
2027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <array-type>
2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <pointer-to-member-type>
2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <template-param>
2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <template-template-param> <template-args>
2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <substitution>
2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= <CV-qualifiers> <type>
2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= P <type>
2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= R <type>
2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= O <type> (C++0x)
2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= C <type>
2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= G <type>
2038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ::= U <source-name> <type>
2039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   <builtin-type> ::= various one letter codes
2041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= u <source-name>
2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst struct demangle_builtin_type_info
2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] =
2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* a */ { NL ("signed char"),	NL ("signed char"),	D_PRINT_DEFAULT },
2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* b */ { NL ("bool"),	NL ("boolean"),		D_PRINT_BOOL },
2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* c */ { NL ("char"),	NL ("byte"),		D_PRINT_DEFAULT },
2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* d */ { NL ("double"),	NL ("double"),		D_PRINT_FLOAT },
2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* e */ { NL ("long double"),	NL ("long double"),	D_PRINT_FLOAT },
2053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* f */ { NL ("float"),	NL ("float"),		D_PRINT_FLOAT },
2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* g */ { NL ("__float128"),	NL ("__float128"),	D_PRINT_FLOAT },
2055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* h */ { NL ("unsigned char"), NL ("unsigned char"),	D_PRINT_DEFAULT },
2056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* i */ { NL ("int"),		NL ("int"),		D_PRINT_INT },
2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* j */ { NL ("unsigned int"), NL ("unsigned"),	D_PRINT_UNSIGNED },
2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* k */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* l */ { NL ("long"),	NL ("long"),		D_PRINT_LONG },
2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* m */ { NL ("unsigned long"), NL ("unsigned long"),	D_PRINT_UNSIGNED_LONG },
2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* n */ { NL ("__int128"),	NL ("__int128"),	D_PRINT_DEFAULT },
2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"),
2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    D_PRINT_DEFAULT },
2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* p */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
2065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* q */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
2066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* r */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* s */ { NL ("short"),	NL ("short"),		D_PRINT_DEFAULT },
2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT },
2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* u */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* v */ { NL ("void"),	NL ("void"),		D_PRINT_VOID },
2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* w */ { NL ("wchar_t"),	NL ("char"),		D_PRINT_DEFAULT },
2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* x */ { NL ("long long"),	NL ("long"),		D_PRINT_LONG_LONG },
2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* y */ { NL ("unsigned long long"), NL ("unsigned long long"),
2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    D_PRINT_UNSIGNED_LONG_LONG },
2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* z */ { NL ("..."),		NL ("..."),		D_PRINT_DEFAULT },
2076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 26 */ { NL ("decimal32"),	NL ("decimal32"),	D_PRINT_DEFAULT },
2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 27 */ { NL ("decimal64"),	NL ("decimal64"),	D_PRINT_DEFAULT },
2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 28 */ { NL ("decimal128"),	NL ("decimal128"),	D_PRINT_DEFAULT },
2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 29 */ { NL ("half"),	NL ("half"),		D_PRINT_FLOAT },
2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 30 */ { NL ("char16_t"),	NL ("char16_t"),	D_PRINT_DEFAULT },
2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* 31 */ { NL ("char32_t"),	NL ("char32_t"),	D_PRINT_DEFAULT },
2082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  /* 32 */ { NL ("decltype(nullptr)"),	NL ("decltype(nullptr)"),
2083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     D_PRINT_DEFAULT },
2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
2085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct demangle_component *
2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_type (struct d_info *di)
2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
2091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret = NULL;
2092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int can_subst;
2093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The ABI specifies that when CV-qualifiers are used, the base type
2095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     is substitutable, and the fully qualified type is substitutable,
2096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     but the base type with a strict subset of the CV-qualifiers is
2097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     not substitutable.  The natural recursive implementation of the
2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     CV-qualifiers would cause subsets to be substitutable, so instead
2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     we pull them all off now.
2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     FIXME: The ABI says that order-insensitive vendor qualifiers
2102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     should be handled in the same way, but we have no way to tell
2103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     which vendor qualifiers are order-insensitive and which are
2104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     order-sensitive.  So we just assume that they are all
2105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     order-sensitive.  g++ 3.4 supports only one vendor qualifier,
2106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     __vector, and it treats it as order-sensitive when mangling
2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     names.  */
2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == 'r' || peek == 'V' || peek == 'K')
2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component **pret;
2113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pret = d_cv_qualifiers (di, &ret, 0);
2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (pret == NULL)
2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *pret = cplus_demangle_type (di);
2118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! *pret || ! d_add_substitution (di, ret))
2119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ret;
2121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  can_subst = 1;
2124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (peek)
2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
2128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'h': case 'i': case 'j':           case 'l': case 'm': case 'n':
2129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'o':                               case 's': case 't':
2130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'v': case 'w': case 'x': case 'y': case 'z':
2131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_builtin_type (di,
2132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				 &cplus_demangle_builtin_types[peek - 'a']);
2133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      di->expansion += ret->u.s_builtin.type->len;
2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      can_subst = 0;
2135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'u':
2139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE,
2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 d_source_name (di), NULL);
2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'F':
2145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_function_type (di);
2146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case '0': case '1': case '2': case '3': case '4':
2149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case '5': case '6': case '7': case '8': case '9':
2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'N':
2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'Z':
2152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_class_enum_type (di);
2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'A':
2156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_array_type (di);
2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'M':
2160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_pointer_to_member_type (di);
2161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'T':
2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_template_param (di);
2165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'I')
2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* This is <template-template-param> <template-args>.  The
2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     <template-template-param> part is a substitution
2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     candidate.  */
2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! d_add_substitution (di, ret))
2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
2172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
2173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			     d_template_args (di));
2174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'S':
2178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If this is a special substitution, then it is the start of
2179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 <class-enum-type>.  */
2180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
2181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	char peek_next;
2182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	peek_next = d_peek_next_char (di);
2184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (IS_DIGIT (peek_next)
2185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    || peek_next == '_'
2186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    || IS_UPPER (peek_next))
2187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
2188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = d_substitution (di, 0);
2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* The substituted name may have been a template name and
2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       may be followed by tepmlate args.  */
2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (d_peek_char (di) == 'I')
2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
2193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				 d_template_args (di));
2194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    else
2195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      can_subst = 0;
2196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	else
2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
2199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = d_class_enum_type (di);
2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* If the substitution was a complete type, then it is not
2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       a new substitution candidate.  However, if the
2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       substitution was followed by template arguments, then
2203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       the whole thing is a substitution candidate.  */
2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (ret != NULL && ret->type == DEMANGLE_COMPONENT_SUB_STD)
2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      can_subst = 0;
2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'O':
2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_RVALUE_REFERENCE,
2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cplus_demangle_type (di), NULL);
2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'P':
2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_POINTER,
2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 cplus_demangle_type (di), NULL);
2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'R':
2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_REFERENCE,
2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cplus_demangle_type (di), NULL);
2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'C':
2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_COMPLEX,
2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 cplus_demangle_type (di), NULL);
2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'G':
2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_IMAGINARY,
2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 cplus_demangle_type (di), NULL);
2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'U':
2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_source_name (di);
2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 cplus_demangle_type (di), ret);
2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'D':
2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      can_subst = 0;
2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_next_char (di);
2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (peek)
2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'T':
2254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 't':
2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* decltype (expression) */
2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_comp (di, DEMANGLE_COMPONENT_DECLTYPE,
2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			     d_expression (di), NULL);
2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (ret && d_next_char (di) != 'E')
2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = NULL;
2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'p':
2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* Pack expansion.  */
2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			     cplus_demangle_type (di), NULL);
2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'f':
2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* 32-bit decimal floating point */
2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'd':
2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* 64-bit DFP */
2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[27]);
2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'e':
2279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* 128-bit DFP */
2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[28]);
2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'h':
2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* 16-bit half-precision FP */
2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[29]);
2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 's':
2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* char16_t */
2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]);
2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'i':
2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* char32_t */
2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += ret->u.s_builtin.type->len;
2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	case 'F':
2300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  /* Fixed point types. DF<int bits><length><fract bits><sat>  */
2301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  ret = d_make_empty (di);
2302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  ret->type = DEMANGLE_COMPONENT_FIXED_TYPE;
2303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if ((ret->u.s_fixed.accum = IS_DIGIT (d_peek_char (di))))
2304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    /* For demangling we don't care about the bits.  */
2305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_number (di);
2306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  ret->u.s_fixed.length = cplus_demangle_type (di);
2307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if (ret->u.s_fixed.length == NULL)
2308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    return NULL;
2309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_number (di);
2310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  peek = d_next_char (di);
2311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  ret->u.s_fixed.sat = (peek == 's');
2312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  break;
2313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	case 'v':
2315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  ret = d_vector_type (di);
2316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  break;
2317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        case 'n':
2319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          /* decltype(nullptr) */
2320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[32]);
2321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  di->expansion += ret->u.s_builtin.type->len;
2322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  break;
2323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	default:
2325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  return NULL;
2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (can_subst)
2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_add_substitution (di, ret))
2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <CV-qualifiers> ::= [r] [V] [K]  */
2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component **
2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_cv_qualifiers (struct d_info *di,
2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 struct demangle_component **pret, int member_fn)
2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component **pstart;
2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  pstart = pret;
2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (peek == 'r' || peek == 'V' || peek == 'K')
2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      enum demangle_component_type t;
2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (peek == 'r')
2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  t = (member_fn
2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       ? DEMANGLE_COMPONENT_RESTRICT_THIS
2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       : DEMANGLE_COMPONENT_RESTRICT);
2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += sizeof "restrict";
2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (peek == 'V')
2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  t = (member_fn
2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       ? DEMANGLE_COMPONENT_VOLATILE_THIS
2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       : DEMANGLE_COMPONENT_VOLATILE);
2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += sizeof "volatile";
2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  t = (member_fn
2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       ? DEMANGLE_COMPONENT_CONST_THIS
2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       : DEMANGLE_COMPONENT_CONST);
2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  di->expansion += sizeof "const";
2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *pret = d_make_comp (di, t, NULL, NULL);
2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (*pret == NULL)
2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pret = &d_left (*pret);
2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      peek = d_peek_char (di);
2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (!member_fn && peek == 'F')
2389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
2390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      while (pstart != pret)
2391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
2392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  switch ((*pstart)->type)
2393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    {
2394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    case DEMANGLE_COMPONENT_RESTRICT:
2395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      (*pstart)->type = DEMANGLE_COMPONENT_RESTRICT_THIS;
2396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      break;
2397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    case DEMANGLE_COMPONENT_VOLATILE:
2398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      (*pstart)->type = DEMANGLE_COMPONENT_VOLATILE_THIS;
2399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      break;
2400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    case DEMANGLE_COMPONENT_CONST:
2401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      (*pstart)->type = DEMANGLE_COMPONENT_CONST_THIS;
2402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      break;
2403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    default:
2404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      break;
2405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    }
2406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  pstart = &d_left (*pstart);
2407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
2408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
2409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return pret;
2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <function-type> ::= F [Y] <bare-function-type> E  */
2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_function_type (struct d_info *di)
2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'F'))
2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == 'Y')
2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Function has C linkage.  We don't print this information.
2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 FIXME: We should print it in verbose mode.  */
2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ret = d_bare_function_type (di, 1);
2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'E'))
2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* <type>+ */
2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_parmlist (struct d_info *di)
2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *tl;
2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **ptl;
2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  tl = NULL;
2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ptl = &tl;
2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *type;
2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      char peek = d_peek_char (di);
2449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (peek == '\0' || peek == 'E' || peek == '.')
2450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	break;
2451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      type = cplus_demangle_type (di);
2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (type == NULL)
2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL);
2455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (*ptl == NULL)
2456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	return NULL;
2457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ptl = &d_right (*ptl);
2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* There should be at least one parameter type besides the optional
2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     return type.  A function which takes no arguments will have a
2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     single parameter type void.  */
2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (tl == NULL)
2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* If we have a single parameter type void, omit it.  */
2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_right (tl) == NULL
2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      && d_left (tl)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      && d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID)
2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      di->expansion -= d_left (tl)->u.s_builtin.type->len;
2472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_left (tl) = NULL;
2473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
2474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return tl;
2476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
2477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* <bare-function-type> ::= [J]<type>+  */
2479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
2481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_bare_function_type (struct d_info *di, int has_return_tipe)
2482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
2483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *return_type;
2484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *tl;
2485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  char peek;
2486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  /* Detect special qualifier indicating that the first argument
2488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng     is the return type.  */
2489663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  peek = d_peek_char (di);
2490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (peek == 'J')
2491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
2492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_advance (di, 1);
2493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      has_return_tipe = 1;
2494663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
2495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (has_return_tipe)
2497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
2498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return_type = cplus_demangle_type (di);
2499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (return_type == NULL)
2500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	return NULL;
2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  else
2503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return_type = NULL;
2504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  tl = d_parmlist (di);
2506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (tl == NULL)
2507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE,
2510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		      return_type, tl);
2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <class-enum-type> ::= <name>  */
2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_class_enum_type (struct d_info *di)
2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_name (di);
2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <array-type> ::= A <(positive dimension) number> _ <(element) type>
2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= A [<(dimension) expression>] _ <(element) type>
2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_array_type (struct d_info *di)
2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *dim;
2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'A'))
2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == '_')
2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    dim = NULL;
2537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (IS_DIGIT (peek))
2538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const char *s;
2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      s = d_str (di);
2542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      do
2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  peek = d_peek_char (di);
2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (IS_DIGIT (peek));
2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dim = d_make_name (di, s, d_str (di) - s);
2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dim == NULL)
2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
2553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dim = d_expression (di);
2555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dim == NULL)
2556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, '_'))
2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim,
2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      cplus_demangle_type (di));
2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* <vector-type> ::= Dv <number> _ <type>
2567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                 ::= Dv _ <expression> _ <type> */
2568663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2569663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
2570663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_vector_type (struct d_info *di)
2571663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
2572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  char peek;
2573663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *dim;
2574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  peek = d_peek_char (di);
2576663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (peek == '_')
2577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
2578663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_advance (di, 1);
2579663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      dim = d_expression (di);
2580663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
2581663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  else
2582663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    dim = d_number_component (di);
2583663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (dim == NULL)
2585663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
2586663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2587663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_check_char (di, '_'))
2588663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
2589663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2590663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return d_make_comp (di, DEMANGLE_COMPONENT_VECTOR_TYPE, dim,
2591663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		      cplus_demangle_type (di));
2592663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
2593663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <pointer-to-member-type> ::= M <(class) type> <(member) type>  */
2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_pointer_to_member_type (struct d_info *di)
2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *cl;
2600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *mem;
2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **pmem;
2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'M'))
2604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  cl = cplus_demangle_type (di);
2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* The ABI specifies that any type can be a substitution source, and
2609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     that M is followed by two types, and that when a CV-qualified
2610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     type is seen both the base type and the CV-qualified types are
2611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     substitution sources.  The ABI also specifies that for a pointer
2612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     to a CV-qualified member function, the qualifiers are attached to
2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     the second type.  Given the grammar, a plain reading of the ABI
2614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     suggests that both the CV-qualified member function and the
2615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     non-qualified member function are substitution sources.  However,
2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     g++ does not work that way.  g++ treats only the CV-qualified
2617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     member function as a substitution source.  FIXME.  So to work
2618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     with g++, we need to pull off the CV-qualifiers here, in order to
2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     avoid calling add_substitution() in cplus_demangle_type().  But
2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     for a CV-qualified member which is not a function, g++ does
2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     follow the ABI, so we need to handle that case here by calling
2622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     d_add_substitution ourselves.  */
2623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pmem = d_cv_qualifiers (di, &mem, 1);
2625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (pmem == NULL)
2626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *pmem = cplus_demangle_type (di);
2628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (*pmem == NULL)
2629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
2632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_add_substitution (di, mem))
2634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
2638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2640663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* <non-negative number> _ */
2641663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic long
2643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_compact_number (struct d_info *di)
2644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
2645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  long num;
2646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (d_peek_char (di) == '_')
2647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    num = 0;
2648663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  else if (d_peek_char (di) == 'n')
2649663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return -1;
2650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  else
2651663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    num = d_number (di) + 1;
2652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_check_char (di, '_'))
2654663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return -1;
2655663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return num;
2656663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
2657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <template-param> ::= T_
2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ::= T <(parameter-2 non-negative) number> _
2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_param (struct d_info *di)
2664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long param;
2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'T'))
2668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  param = d_compact_number (di);
2671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (param < 0)
2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ++di->did_subs;
2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_make_template_param (di, param);
2677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <template-args> ::= I <template-arg>+ E  */
2680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_args (struct d_info *di)
2683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *hold_last_name;
2685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *al;
2686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **pal;
2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Preserve the last name we saw--don't let the template arguments
2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     clobber it, as that would give us the wrong name for a subsequent
2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     constructor or destructor.  */
2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hold_last_name = di->last_name;
2692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'I'))
2694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == 'E')
2697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* An argument pack can be empty.  */
2699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, NULL, NULL);
2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  al = NULL;
2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pal = &al;
2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *a;
2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = d_template_arg (di);
2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (a == NULL)
2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *pal = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, a, NULL);
2714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (*pal == NULL)
2715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pal = &d_right (*pal);
2717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'E')
2719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
2721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->last_name = hold_last_name;
2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return al;
2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <template-arg> ::= <type>
2731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= X <expression> E
2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= <expr-primary>
2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_template_arg (struct d_info *di)
2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (d_peek_char (di))
2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'X':
2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_expression (di);
2745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_check_char (di, 'E'))
2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ret;
2748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'L':
2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_expr_primary (di);
2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case 'I':
2753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* An argument pack.  */
2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_template_args (di);
2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return cplus_demangle_type (di);
2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Subroutine of <expression> ::= cl <expression>+ E */
2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_exprlist (struct d_info *di)
2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *list = NULL;
2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component **p = &list;
2768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == 'E')
2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
2772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL);
2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (1)
2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *arg = d_expression (di);
2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (arg == NULL)
2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *p = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, arg, NULL);
2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (*p == NULL)
2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p = &d_right (*p);
2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'E')
2787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return list;
2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <expression> ::= <(unary) operator-name> <expression>
2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= <(binary) operator-name> <expression> <expression>
2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= <(trinary) operator-name> <expression> <expression> <expression>
2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		::= cl <expression>+ E
2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= st <type>
2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= <template-param>
2802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= sr <type> <unqualified-name>
2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= sr <type> <unqualified-name> <template-args>
2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= <expr-primary>
2805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_expression (struct d_info *di)
2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char peek;
2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  peek = d_peek_char (di);
2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (peek == 'L')
2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_expr_primary (di);
2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (peek == 'T')
2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return d_template_param (di);
2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (peek == 's' && d_peek_next_char (di) == 'r')
2818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *type;
2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *name;
2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 2);
2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      type = cplus_demangle_type (di);
2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      name = d_unqualified_name (di);
2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) != 'I')
2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name);
2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type,
2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					 d_template_args (di)));
2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  else if (peek == 's' && d_peek_next_char (di) == 'p')
2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 2);
2835663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
2836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng			  d_expression (di), NULL);
2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  else if (peek == 'f' && d_peek_next_char (di) == 'p')
2839663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
2840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Function parameter used in a late-specified return type.  */
2841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      int index;
2842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_advance (di, 2);
2843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (d_peek_char (di) == 'T')
2844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
2845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  /* 'this' parameter.  */
2846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_advance (di, 1);
2847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  index = 0;
2848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
2849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      else
2850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
2851663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  index = d_compact_number (di) + 1;
2852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if (index == 0)
2853663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    return NULL;
2854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
2855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return d_make_function_param (di, index);
2856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
2857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  else if (IS_DIGIT (peek)
2858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	   || (peek == 'o' && d_peek_next_char (di) == 'n'))
2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We can get an unqualified name as an expression in the case of
2861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         a dependent function call, i.e. decltype(f(t)).  */
2862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      struct demangle_component *name;
2863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (peek == 'o')
2865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	/* operator-function-id, i.e. operator+(t).  */
2866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_advance (di, 2);
2867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
2868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      name = d_unqualified_name (di);
2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (name == NULL)
2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'I')
2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    d_template_args (di));
2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return name;
2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
2878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *op;
2880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int args;
2881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      op = d_operator_name (di);
2883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (op == NULL)
2884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (op->type == DEMANGLE_COMPONENT_OPERATOR)
2887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion += op->u.s_operator.op->len - 2;
2888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (op->type == DEMANGLE_COMPONENT_OPERATOR
2890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && strcmp (op->u.s_operator.op->code, "st") == 0)
2891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
2892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    cplus_demangle_type (di));
2893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (op->type)
2895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
2897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return NULL;
2898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_OPERATOR:
2899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  args = op->u.s_operator.op->args;
2900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
2902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  args = op->u.s_extended_operator.args;
2903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_CAST:
2905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  args = 1;
2906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
2907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (args)
2910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
2911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 1:
2912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  {
2913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    struct demangle_component *operand;
2914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    if (op->type == DEMANGLE_COMPONENT_CAST
2915663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		&& d_check_char (di, '_'))
2916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      operand = d_exprlist (di);
2917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    else
2918663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      operand = d_expression (di);
2919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
2920663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng				operand);
2921663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  }
2922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 2:
2923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
2924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *left;
2925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *right;
2926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    const char *code = op->u.s_operator.op->code;
2927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    left = d_expression (di);
2929663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    if (!strcmp (code, "cl"))
2930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      right = d_exprlist (di);
2931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    else if (!strcmp (code, "dt") || !strcmp (code, "pt"))
2932663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      {
2933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		right = d_unqualified_name (di);
2934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		if (d_peek_char (di) == 'I')
2935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		  right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE,
2936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng				       right, d_template_args (di));
2937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      }
2938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    else
2939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      right = d_expression (di);
2940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op,
2942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				d_make_comp (di,
2943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     DEMANGLE_COMPONENT_BINARY_ARGS,
2944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     left, right));
2945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
2946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 3:
2947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
2948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *first;
2949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *second;
2950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    first = d_expression (di);
2952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    second = d_expression (di);
2953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op,
2954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				d_make_comp (di,
2955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     DEMANGLE_COMPONENT_TRINARY_ARG1,
2956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     first,
2957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					     d_make_comp (di,
2958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown							  DEMANGLE_COMPONENT_TRINARY_ARG2,
2959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown							  second,
2960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown							  d_expression (di))));
2961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
2962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
2963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return NULL;
2964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
2965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
2966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <expr-primary> ::= L <type> <(value) number> E
2969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= L <type> <(value) float> E
2970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= L <mangled-name> E
2971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
2974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_expr_primary (struct d_info *di)
2975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *ret;
2977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'L'))
2979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
2980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (d_peek_char (di) == '_'
2981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Workaround for G++ bug; see comment in write_template_arg.  */
2982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      || d_peek_char (di) == 'Z')
2983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ret = cplus_demangle_mangled_name (di, 0);
2984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
2985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
2986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *type;
2987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      enum demangle_component_type t;
2988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const char *s;
2989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      type = cplus_demangle_type (di);
2991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (type == NULL)
2992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
2993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If we have a type we know how to print, we aren't going to
2995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 print the type name itself.  */
2996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
2997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && type->u.s_builtin.type->print != D_PRINT_DEFAULT)
2998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	di->expansion -= type->u.s_builtin.type->len;
2999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Rather than try to interpret the literal value, we just
3001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 collect it as a string.  Note that it's possible to have a
3002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 floating point literal here.  The ABI specifies that the
3003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 format of such literals is machine independent.  That's fine,
3004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 but what's not fine is that versions of g++ up to 3.2 with
3005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 -fabi-version=1 used upper case letters in the hex constant,
3006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 and dumped out gcc's internal representation.  That makes it
3007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 hard to tell where the constant ends, and hard to dump the
3008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 constant in any readable form anyhow.  We don't attempt to
3009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 handle these cases.  */
3010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      t = DEMANGLE_COMPONENT_LITERAL;
3012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_peek_char (di) == 'n')
3013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  t = DEMANGLE_COMPONENT_LITERAL_NEG;
3015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
3016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
3017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      s = d_str (di);
3018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (d_peek_char (di) != 'E')
3019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (d_peek_char (di) == '\0')
3021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return NULL;
3022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_advance (di, 1);
3023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
3024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s));
3025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'E'))
3027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
3028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
3029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <local-name> ::= Z <(function) encoding> E <(entity) name> [<discriminator>]
3032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ::= Z <(function) encoding> E s [<discriminator>]
3033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
3034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
3036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_local_name (struct d_info *di)
3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *function;
3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'Z'))
3041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  function = d_encoding (di, 0);
3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'E'))
3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) == 's')
3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_advance (di, 1);
3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! d_discriminator (di))
3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function,
3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			  d_make_name (di, "string literal",
3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				       sizeof "string literal" - 1));
3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *name;
3060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      int num = -1;
3061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (d_peek_char (di) == 'd')
3063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
3064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  /* Default argument scope: d <number> _.  */
3065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_advance (di, 1);
3066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  num = d_compact_number (di);
3067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if (num < 0)
3068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    return NULL;
3069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      name = d_name (di);
3072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (name)
3073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	switch (name->type)
3074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  {
3075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    /* Lambdas and unnamed types have internal discriminators.  */
3076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  case DEMANGLE_COMPONENT_LAMBDA:
3077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  case DEMANGLE_COMPONENT_UNNAMED_TYPE:
3078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    break;
3079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  default:
3080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    if (! d_discriminator (di))
3081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      return NULL;
3082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  }
3083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (num >= 0)
3084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	name = d_make_default_arg (di, num, name);
3085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name);
3086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <discriminator> ::= _ <(non-negative) number>
3090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   We demangle the discriminator, but we don't print it out.  FIXME:
3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   We should print it out in verbose mode.  */
3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_discriminator (struct d_info *di)
3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  long discrim;
3098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_peek_char (di) != '_')
3100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 1;
3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_advance (di, 1);
3102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  discrim = d_number (di);
3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (discrim < 0)
3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ */
3109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
3111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_lambda (struct d_info *di)
3112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
3113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *tl;
3114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *ret;
3115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  int num;
3116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_check_char (di, 'U'))
3118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_check_char (di, 'l'))
3120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  tl = d_parmlist (di);
3123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (tl == NULL)
3124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_check_char (di, 'E'))
3127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  num = d_compact_number (di);
3130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (num < 0)
3131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ret = d_make_empty (di);
3134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (ret)
3135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
3136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ret->type = DEMANGLE_COMPONENT_LAMBDA;
3137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ret->u.s_unary_num.sub = tl;
3138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ret->u.s_unary_num.num = num;
3139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
3140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_add_substitution (di, ret))
3142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return ret;
3145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
3146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */
3148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
3150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_unnamed_type (struct d_info *di)
3151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
3152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *ret;
3153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  long num;
3154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_check_char (di, 'U'))
3156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_check_char (di, 't'))
3158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  num = d_compact_number (di);
3161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (num < 0)
3162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  ret = d_make_empty (di);
3165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (ret)
3166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
3167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ret->type = DEMANGLE_COMPONENT_UNNAMED_TYPE;
3168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ret->u.s_number.number = num;
3169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
3170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (! d_add_substitution (di, ret))
3172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    return NULL;
3173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return ret;
3175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
3176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]*
3178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/
3179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic struct demangle_component *
3181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_clone_suffix (struct d_info *di, struct demangle_component *encoding)
3182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
3183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  const char *suffix = d_str (di);
3184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  const char *pend = suffix;
3185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  struct demangle_component *n;
3186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (*pend == '.' && (IS_LOWER (pend[1]) || pend[1] == '_'))
3188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
3189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      pend += 2;
3190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      while (IS_LOWER (*pend) || *pend == '_')
3191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	++pend;
3192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
3193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  while (*pend == '.' && IS_DIGIT (pend[1]))
3194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
3195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      pend += 2;
3196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      while (IS_DIGIT (*pend))
3197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	++pend;
3198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
3199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_advance (di, pend - suffix);
3200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  n = d_make_name (di, suffix, pend - suffix);
3201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  return d_make_comp (di, DEMANGLE_COMPONENT_CLONE, encoding, n);
3202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
3203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a new substitution.  */
3205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
3207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_add_substitution (struct d_info *di, struct demangle_component *dc)
3208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
3210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
3211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (di->next_sub >= di->num_subs)
3212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return 0;
3213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->subs[di->next_sub] = dc;
3214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  ++di->next_sub;
3215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 1;
3216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* <substitution> ::= S <seq-id> _
3219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= S_
3220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= St
3221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Sa
3222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Sb
3223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Ss
3224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Si
3225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= So
3226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  ::= Sd
3227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   If PREFIX is non-zero, then this type is being used as a prefix in
3229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a qualified name.  In this case, for the standard substitutions, we
3230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   need to check whether we are being used as a prefix for a
3231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   constructor or destructor, and return a full template name.
3232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Otherwise we will get something like std::iostream::~iostream()
3233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   which does not correspond particularly well to any function which
3234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   actually appears in the source.
3235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
3236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const struct d_standard_sub_info standard_subs[] =
3238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 't', NL ("std"),
3240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std"),
3241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NULL, 0 },
3242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'a', NL ("std::allocator"),
3243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::allocator"),
3244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("allocator") },
3245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'b', NL ("std::basic_string"),
3246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_string"),
3247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_string") },
3248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 's', NL ("std::string"),
3249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
3250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_string") },
3251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'i', NL ("std::istream"),
3252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_istream<char, std::char_traits<char> >"),
3253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_istream") },
3254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'o', NL ("std::ostream"),
3255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_ostream<char, std::char_traits<char> >"),
3256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_ostream") },
3257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { 'd', NL ("std::iostream"),
3258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("std::basic_iostream<char, std::char_traits<char> >"),
3259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    NL ("basic_iostream") }
3260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
3261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
3263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_substitution (struct d_info *di, int prefix)
3264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char c;
3266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! d_check_char (di, 'S'))
3268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
3269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  c = d_next_char (di);
3271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (c == '_' || IS_DIGIT (c) || IS_UPPER (c))
3272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned int id;
3274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      id = 0;
3276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (c != '_')
3277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  do
3279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
3280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      unsigned int new_id;
3281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (IS_DIGIT (c))
3283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		new_id = id * 36 + c - '0';
3284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else if (IS_UPPER (c))
3285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		new_id = id * 36 + c - 'A' + 10;
3286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
3287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		return NULL;
3288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (new_id < id)
3289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		return NULL;
3290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      id = new_id;
3291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = d_next_char (di);
3292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
3293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  while (c != '_');
3294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  ++id;
3296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
3297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (id >= (unsigned int) di->next_sub)
3299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
3300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ++di->did_subs;
3302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return di->subs[id];
3304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int verbose;
3308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const struct d_standard_sub_info *p;
3309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      const struct d_standard_sub_info *pend;
3310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      verbose = (di->options & DMGL_VERBOSE) != 0;
3312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! verbose && prefix)
3313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  char peek;
3315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  peek = d_peek_char (di);
3317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (peek == 'C' || peek == 'D')
3318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    verbose = 1;
3319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
3320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pend = (&standard_subs[0]
3322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      + sizeof standard_subs / sizeof standard_subs[0]);
3323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (p = &standard_subs[0]; p < pend; ++p)
3324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
3325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (c == p->code)
3326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
3327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      const char *s;
3328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      int len;
3329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (p->set_last_name != NULL)
3331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		di->last_name = d_make_sub (di, p->set_last_name,
3332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown					    p->set_last_name_len);
3333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (verbose)
3334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
3335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  s = p->full_expansion;
3336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  len = p->full_len;
3337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
3338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
3339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
3340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  s = p->simple_expansion;
3341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  len = p->simple_len;
3342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
3343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      di->expansion += len;
3344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return d_make_sub (di, s, len);
3345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
3346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
3347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialize a growable string.  */
3353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
3355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_init (struct d_growable_string *dgs, size_t estimate)
3356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->buf = NULL;
3358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->len = 0;
3359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->alc = 0;
3360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->allocation_failure = 0;
3361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (estimate > 0)
3363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_growable_string_resize (dgs, estimate);
3364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Grow a growable string to a given size.  */
3367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_resize (struct d_growable_string *dgs, size_t need)
3370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t newalc;
3372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char *newbuf;
3373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dgs->allocation_failure)
3375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return;
3376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Start allocation at two bytes to avoid any possibility of confusion
3378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     with the special value of 1 used as a return in *palc to indicate
3379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     allocation failures.  */
3380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  newalc = dgs->alc > 0 ? dgs->alc : 2;
3381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (newalc < need)
3382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    newalc <<= 1;
3383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  newbuf = (char *) realloc ("demangle.dgsr.1", dgs->buf, newalc);
3385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (newbuf == NULL)
3386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      free (dgs->buf);
3388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dgs->buf = NULL;
3389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dgs->len = 0;
3390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dgs->alc = 0;
3391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dgs->allocation_failure = 1;
3392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->buf = newbuf;
3395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->alc = newalc;
3396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append a buffer to a growable string.  */
3399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_append_buffer (struct d_growable_string *dgs,
3402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 const char *s, size_t l)
3403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t need;
3405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  need = dgs->len + l + 1;
3407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (need > dgs->alc)
3408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_growable_string_resize (dgs, need);
3409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dgs->allocation_failure)
3411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return;
3412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  memcpy (dgs->buf + dgs->len, s, l);
3414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->buf[dgs->len + l] = '\0';
3415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dgs->len += l;
3416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Bridge growable strings to the callback mechanism.  */
3419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
3421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_growable_string_callback_adapter (const char *s, size_t l, void *opaque)
3422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_growable_string *dgs = (struct d_growable_string*) opaque;
3424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_growable_string_append_buffer (dgs, s, l);
3426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialize a print information structure.  */
3429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
3431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_init (struct d_print_info *dpi, demangle_callbackref callback,
3432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      void *opaque)
3433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->len = 0;
3435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->last_char = '\0';
3436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->templates = NULL;
3437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->modifiers = NULL;
3438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  dpi->pack_index = 0;
3439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  dpi->flush_count = 0;
3440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->callback = callback;
3442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->opaque = opaque;
3443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->demangle_failure = 0;
3445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Indicate that an error occurred during printing, and test for error.  */
3448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_error (struct d_print_info *dpi)
3451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->demangle_failure = 1;
3453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline int
3456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_saw_error (struct d_print_info *dpi)
3457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dpi->demangle_failure != 0;
3459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Flush buffered characters to the callback.  */
3462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_flush (struct d_print_info *dpi)
3465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->buf[dpi->len] = '\0';
3467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->callback (dpi->buf, dpi->len, dpi->opaque);
3468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->len = 0;
3469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  dpi->flush_count++;
3470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append characters and buffers for printing.  */
3473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_append_char (struct d_print_info *dpi, char c)
3476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dpi->len == sizeof (dpi->buf) - 1)
3478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_print_flush (dpi);
3479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->buf[dpi->len++] = c;
3481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->last_char = c;
3482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_append_buffer (struct d_print_info *dpi, const char *s, size_t l)
3486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t i;
3488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (i = 0; i < l; i++)
3490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, s[i]);
3491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void
3494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_append_string (struct d_print_info *dpi, const char *s)
3495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_buffer (dpi, s, strlen (s));
3497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic inline void
3500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_append_num (struct d_print_info *dpi, long l)
3501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
3502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  char buf[25];
3503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  sprintf (buf,"%ld", l);
3504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_append_string (dpi, buf);
3505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
3506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline char
3508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_last_char (struct d_print_info *dpi)
3509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dpi->last_char;
3511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Turn components into a human readable string.  OPTIONS is the
3514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   options bits passed to the demangler.  DC is the tree to print.
3515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CALLBACK is a function to call to flush demangled string segments
3516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   as they fill the intermediate buffer, and OPAQUE is a generalized
3517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   callback argument.  On success, this returns 1.  On failure,
3518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   it returns 0, indicating a bad parse.  It does not use heap
3519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   memory to build an output string, so cannot encounter memory
3520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   allocation failure.  */
3521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
3523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
3524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_print_callback (int options,
3525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               const struct demangle_component *dc,
3526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               demangle_callbackref callback, void *opaque)
3527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_info dpi;
3529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3530663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_print_init (&dpi, callback, opaque);
3531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_print_comp (&dpi, options, dc);
3533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_print_flush (&dpi);
3535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ! d_print_saw_error (&dpi);
3537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Turn components into a human readable string.  OPTIONS is the
3540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   options bits passed to the demangler.  DC is the tree to print.
3541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ESTIMATE is a guess at the length of the result.  This returns a
3542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   string allocated by malloc, or NULL on error.  On success, this
3543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sets *PALC to the size of the allocated buffer.  On failure, this
3544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sets *PALC to 0 for a bad parse, or to 1 for a memory allocation
3545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   failure.  */
3546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
3548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar *
3549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_print (int options, const struct demangle_component *dc,
3550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      int estimate, size_t *palc)
3551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_growable_string dgs;
3553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_growable_string_init (&dgs, estimate);
3555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! cplus_demangle_print_callback (options, dc,
3557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                       d_growable_string_callback_adapter,
3558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                       &dgs))
3559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      free (dgs.buf);
3561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *palc = 0;
3562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *palc = dgs.allocation_failure ? 1 : dgs.alc;
3566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dgs.buf;
3567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns the I'th element of the template arglist ARGS, or NULL on
3570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   failure.  */
3571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
3573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_index_template_argument (struct demangle_component *args, int i)
3574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *a;
3576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (a = args;
3578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       a != NULL;
3579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       a = d_right (a))
3580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
3582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return NULL;
3583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i <= 0)
3584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	break;
3585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      --i;
3586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (i != 0 || a == NULL)
3588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
3589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_left (a);
3591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns the template argument from the current context indicated by DC,
3594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   which is a DEMANGLE_COMPONENT_TEMPLATE_PARAM, or NULL.  */
3595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
3597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_lookup_template_argument (struct d_print_info *dpi,
3598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			    const struct demangle_component *dc)
3599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dpi->templates == NULL)
3601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
3603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_index_template_argument
3607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (d_right (dpi->templates->template_decl),
3608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     dc->u.s_number.number);
3609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns a template argument pack used in DC (any will do), or NULL.  */
3612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct demangle_component *
3614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_find_pack (struct d_print_info *dpi,
3615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     const struct demangle_component *dc)
3616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *a;
3618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
3619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return NULL;
3620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
3622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
3624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = d_lookup_template_argument (dpi, dc);
3625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
3626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return a;
3627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PACK_EXPANSION:
3630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3632663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_LAMBDA:
3633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_NAME:
3634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_OPERATOR:
3635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
3636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_SUB_STD:
3637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CHARACTER:
3638663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_FUNCTION_PARAM:
3639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
3640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
3642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_find_pack (dpi, dc->u.s_extended_operator.name);
3643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CTOR:
3644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_find_pack (dpi, dc->u.s_ctor.name);
3645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DTOR:
3646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_find_pack (dpi, dc->u.s_dtor.name);
3647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
3649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a = d_find_pack (dpi, d_left (dc));
3650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (a)
3651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return a;
3652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return d_find_pack (dpi, d_right (dc));
3653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns the length of the template argument pack DC.  */
3657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
3659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_pack_length (const struct demangle_component *dc)
3660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int count = 0;
3662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST
3663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 && d_left (dc) != NULL)
3664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ++count;
3666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = d_right (dc);
3667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return count;
3669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DC is a component of a mangled expression.  Print it, wrapped in parens
3672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if needed.  */
3673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
3675663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_subexpr (struct d_print_info *dpi, int options,
3676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		 const struct demangle_component *dc)
3677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int simple = 0;
3679663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  if (dc->type == DEMANGLE_COMPONENT_NAME
3680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      || dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM)
3681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    simple = 1;
3682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (!simple)
3683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, '(');
3684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_print_comp (dpi, options, dc);
3685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (!simple)
3686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, ')');
3687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Subroutine to handle components.  */
3690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
3692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_comp (struct d_print_info *dpi, int options,
3693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              const struct demangle_component *dc)
3694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  /* Magic variable to let reference smashing skip over the next modifier
3696663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng     without needing to modify *dc.  */
3697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  const struct demangle_component *mod_inner = NULL;
3698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc == NULL)
3700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
3702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
3704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_print_saw_error (dpi))
3705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return;
3706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (dc->type)
3708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
3709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_NAME:
3710663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if ((options & DMGL_JAVA) == 0)
3711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_buffer (dpi, dc->u.s_name.s, dc->u.s_name.len);
3712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
3713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_print_java_identifier (dpi, dc->u.s_name.s, dc->u.s_name.len);
3714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_QUAL_NAME:
3717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LOCAL_NAME:
3718663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3719663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if ((options & DMGL_JAVA) == 0)
3720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_string (dpi, "::");
3721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
3722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '.');
3723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_right (dc));
3724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPED_NAME:
3727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *hold_modifiers;
3729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct demangle_component *typed_name;
3730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod adpm[4];
3731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	unsigned int i;
3732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_template dpt;
3733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* Pass the name down to the type so that it can be printed in
3735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   the right place for the type.  We also have to pass down
3736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   any CV-qualifiers, which apply to the this parameter.  */
3737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	hold_modifiers = dpi->modifiers;
3738663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	dpi->modifiers = 0;
3739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	i = 0;
3740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	typed_name = d_left (dc);
3741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	while (typed_name != NULL)
3742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (i >= sizeof adpm / sizeof adpm[0])
3744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
3745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		d_print_error (dpi);
3746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		return;
3747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
3748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    adpm[i].next = dpi->modifiers;
3750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->modifiers = &adpm[i];
3751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    adpm[i].mod = typed_name;
3752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    adpm[i].printed = 0;
3753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    adpm[i].templates = dpi->templates;
3754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ++i;
3755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS
3757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		&& typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS
3758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		&& typed_name->type != DEMANGLE_COMPONENT_CONST_THIS)
3759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      break;
3760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    typed_name = d_left (typed_name);
3762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (typed_name == NULL)
3765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_error (dpi);
3767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return;
3768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If typed_name is a template, then it applies to the
3771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   function type as well.  */
3772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
3773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpt.next = dpi->templates;
3775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->templates = &dpt;
3776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpt.template_decl = typed_name;
3777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If typed_name is a DEMANGLE_COMPONENT_LOCAL_NAME, then
3780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   there may be CV-qualifiers on its right argument which
3781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   really apply here; this happens when parsing a class which
3782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   is local to a function.  */
3783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (typed_name->type == DEMANGLE_COMPONENT_LOCAL_NAME)
3784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct demangle_component *local_name;
3786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    local_name = d_right (typed_name);
3788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
3789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      local_name = local_name->u.s_unary_num.sub;
3790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
3791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
3792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   || local_name->type == DEMANGLE_COMPONENT_CONST_THIS)
3793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
3794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (i >= sizeof adpm / sizeof adpm[0])
3795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
3796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    d_print_error (dpi);
3797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    return;
3798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
3799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i] = adpm[i - 1];
3801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i].next = &adpm[i - 1];
3802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dpi->modifiers = &adpm[i];
3803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i - 1].mod = local_name;
3805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i - 1].printed = 0;
3806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i - 1].templates = dpi->templates;
3807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		++i;
3808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		local_name = d_left (local_name);
3810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
3811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_comp (dpi, options, d_right (dc));
3814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
3816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  dpi->templates = dpt.next;
3817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If the modifiers didn't get printed by the type, print them
3819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   now.  */
3820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	while (i > 0)
3821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    --i;
3823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! adpm[i].printed)
3824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
3825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		d_append_char (dpi, ' ');
3826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		d_print_mod (dpi, options, adpm[i].mod);
3827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
3828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = hold_modifiers;
3831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE:
3836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *hold_dpm;
3838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct demangle_component *dcl;
3839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* Don't push modifiers into a template definition.  Doing so
3841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   could give the wrong definition for a template argument.
3842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   Instead, treat the template essentially as a name.  */
3843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	hold_dpm = dpi->modifiers;
3845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = NULL;
3846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        dcl = d_left (dc);
3848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        if ((options & DMGL_JAVA) != 0
3850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            && dcl->type == DEMANGLE_COMPONENT_NAME
3851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            && dcl->u.s_name.len == 6
3852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            && strncmp (dcl->u.s_name.s, "JArray", 6) == 0)
3853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          {
3854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* Special-case Java arrays, so that JArray<TYPE> appears
3855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               instead as TYPE[].  */
3856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            d_print_comp (dpi, options, d_right (dc));
3858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            d_append_string (dpi, "[]");
3859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          }
3860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        else
3861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          {
3862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_print_comp (dpi, options, dcl);
3863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (d_last_char (dpi) == '<')
3864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_char (dpi, ' ');
3865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_append_char (dpi, '<');
3866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_print_comp (dpi, options, d_right (dc));
3867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* Avoid generating two consecutive '>' characters, to avoid
3868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       the C++ syntactic ambiguity.  */
3869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (d_last_char (dpi) == '>')
3870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_char (dpi, ' ');
3871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_append_char (dpi, '>');
3872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          }
3873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = hold_dpm;
3875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
3880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_template *hold_dpt;
3882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct demangle_component *a = d_lookup_template_argument (dpi, dc);
3883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
3885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  a = d_index_template_argument (a, dpi->pack_index);
3886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (a == NULL)
3888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
3889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    d_print_error (dpi);
3890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    return;
3891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
3892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* While processing this parameter, we need to pop the list of
3894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   templates.  This is because the template parameter may
3895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   itself be a reference to a parameter of an outer
3896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   template.  */
3897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	hold_dpt = dpi->templates;
3899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->templates = hold_dpt->next;
3900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_comp (dpi, options, a);
3902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->templates = hold_dpt;
3904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
3906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CTOR:
3909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, dc->u.s_ctor.name);
3910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DTOR:
3913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '~');
3914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, dc->u.s_dtor.name);
3915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTABLE:
3918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "vtable for ");
3919663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VTT:
3923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "VTT for ");
3924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
3928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "construction vtable for ");
3929663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "-in-");
3931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_right (dc));
3932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO:
3935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "typeinfo for ");
3936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_NAME:
3940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "typeinfo name for ");
3941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPEINFO_FN:
3945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "typeinfo fn for ");
3946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_THUNK:
3950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "non-virtual thunk to ");
3951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
3955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "virtual thunk to ");
3956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COVARIANT_THUNK:
3960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "covariant return thunk to ");
3961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_CLASS:
3965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "java Class for ");
3966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_GUARD:
3970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "guard variable for ");
3971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFTEMP:
3975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, "reference temporary #");
3976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_right (dc));
3977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, " for ");
3978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
3982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "hidden alias for ");
3983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
3985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
3987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, "transaction clone for ");
3988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
3990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
3992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, "non-transaction clone for ");
3993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
3994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_SUB_STD:
3997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_buffer (dpi, dc->u.s_string.string, dc->u.s_string.len);
3998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
3999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT:
4001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE:
4002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST:
4003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
4004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *pdpm;
4005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* When printing arrays, it's possible to have cases where the
4007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   same CV-qualifier gets pushed on the stack multiple times.
4008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   We only need to print it once.  */
4009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	for (pdpm = dpi->modifiers; pdpm != NULL; pdpm = pdpm->next)
4011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
4012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! pdpm->printed)
4013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
4014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (pdpm->mod->type != DEMANGLE_COMPONENT_RESTRICT
4015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    && pdpm->mod->type != DEMANGLE_COMPONENT_VOLATILE
4016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    && pdpm->mod->type != DEMANGLE_COMPONENT_CONST)
4017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  break;
4018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (pdpm->mod->type == dc->type)
4019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
4020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		    d_print_comp (dpi, options, d_left (dc));
4021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    return;
4022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
4023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
4024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
4025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      goto modifier;
4027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_REFERENCE:
4029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
4030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      {
4031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	/* Handle reference smashing: & + && = &.  */
4032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	const struct demangle_component *sub = d_left (dc);
4033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
4034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  {
4035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    struct demangle_component *a = d_lookup_template_argument (dpi, sub);
4036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
4037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      a = d_index_template_argument (a, dpi->pack_index);
4038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    if (a == NULL)
4040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      {
4041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		d_print_error (dpi);
4042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		return;
4043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	      }
4044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    sub = a;
4046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  }
4047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	if (sub->type == DEMANGLE_COMPONENT_REFERENCE
4049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    || sub->type == dc->type)
4050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  dc = sub;
4051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	else if (sub->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE)
4052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  mod_inner = d_left (sub);
4053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
4054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Fall through.  */
4055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
4057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
4058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
4059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
4060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_POINTER:
4061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPLEX:
4062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_IMAGINARY:
4063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    modifier:
4064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
4065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* We keep a list of modifiers on the stack.  */
4066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod dpm;
4067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.next = dpi->modifiers;
4069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = &dpm;
4070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.mod = dc;
4071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.printed = 0;
4072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.templates = dpi->templates;
4073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	if (!mod_inner)
4075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  mod_inner = d_left (dc);
4076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_comp (dpi, options, mod_inner);
4078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If the modifier didn't get printed by the type, print it
4080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   now.  */
4081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (! dpm.printed)
4082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_mod (dpi, options, dc);
4083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = dpm.next;
4085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
4087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
4090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if ((options & DMGL_JAVA) == 0)
4091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_buffer (dpi, dc->u.s_builtin.type->name,
4092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 dc->u.s_builtin.type->len);
4093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
4094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_buffer (dpi, dc->u.s_builtin.type->java_name,
4095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 dc->u.s_builtin.type->java_len);
4096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE:
4099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
4100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_FUNCTION_TYPE:
4103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
4104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	if ((options & DMGL_RET_POSTFIX) != 0)
4105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_function_type (dpi,
4106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng				 options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
4107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng				 dc, dpi->modifiers);
4108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* Print return type if present */
4110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	if (d_left (dc) != NULL && (options & DMGL_RET_POSTFIX) != 0)
4111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_comp (dpi, options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
4112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng			d_left (dc));
4113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	else if (d_left (dc) != NULL && (options & DMGL_RET_DROP) == 0)
4114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
4115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    struct d_print_mod dpm;
4116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* We must pass this type down as a modifier in order to
4118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       print it in the right location.  */
4119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpm.next = dpi->modifiers;
4120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->modifiers = &dpm;
4121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpm.mod = dc;
4122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpm.printed = 0;
4123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpm.templates = dpi->templates;
4124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_print_comp (dpi, options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
4126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng			  d_left (dc));
4127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->modifiers = dpm.next;
4129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (dpm.printed)
4131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      return;
4132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    /* In standard prefix notation, there is a space between the
4134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       return type and the function signature.  */
4135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    if ((options & DMGL_RET_POSTFIX) == 0)
4136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_char (dpi, ' ');
4137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
4138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	if ((options & DMGL_RET_POSTFIX) == 0)
4140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_function_type (dpi,
4141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng				 options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
4142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng				 dc, dpi->modifiers);
4143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
4145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARRAY_TYPE:
4148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
4149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *hold_modifiers;
4150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod adpm[4];
4151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	unsigned int i;
4152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod *pdpm;
4153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* We must pass this type down as a modifier in order to print
4155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   multi-dimensional arrays correctly.  If the array itself is
4156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   CV-qualified, we act as though the element type were
4157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   CV-qualified.  We do this by copying the modifiers down
4158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   rather than fiddling pointers, so that we don't wind up
4159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   with a d_print_mod higher on the stack pointing into our
4160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   stack frame after we return.  */
4161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	hold_modifiers = dpi->modifiers;
4163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adpm[0].next = hold_modifiers;
4165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = &adpm[0];
4166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adpm[0].mod = dc;
4167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adpm[0].printed = 0;
4168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	adpm[0].templates = dpi->templates;
4169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	i = 1;
4171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pdpm = hold_modifiers;
4172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	while (pdpm != NULL
4173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	       && (pdpm->mod->type == DEMANGLE_COMPONENT_RESTRICT
4174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   || pdpm->mod->type == DEMANGLE_COMPONENT_VOLATILE
4175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   || pdpm->mod->type == DEMANGLE_COMPONENT_CONST))
4176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
4177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (! pdpm->printed)
4178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
4179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (i >= sizeof adpm / sizeof adpm[0])
4180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
4181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    d_print_error (dpi);
4182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    return;
4183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
4184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i] = *pdpm;
4186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		adpm[i].next = dpi->modifiers;
4187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dpi->modifiers = &adpm[i];
4188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		pdpm->printed = 1;
4189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		++i;
4190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
4191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    pdpm = pdpm->next;
4193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
4194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_comp (dpi, options, d_right (dc));
4196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = hold_modifiers;
4198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (adpm[0].printed)
4200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return;
4201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	while (i > 1)
4203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
4204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    --i;
4205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_print_mod (dpi, options, adpm[i].mod);
4206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
4207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_array_type (dpi, options, dc, dpi->modifiers);
4209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
4211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
4214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_VECTOR_TYPE:
4215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
4216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	struct d_print_mod dpm;
4217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.next = dpi->modifiers;
4219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = &dpm;
4220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.mod = dc;
4221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.printed = 0;
4222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpm.templates = dpi->templates;
4223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_comp (dpi, options, d_right (dc));
4225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* If the modifier didn't get printed by the type, print it
4227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   now.  */
4228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (! dpm.printed)
4229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_mod (dpi, options, dc);
4230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dpi->modifiers = dpm.next;
4232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
4234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_FIXED_TYPE:
4237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (dc->u.s_fixed.sat)
4238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_append_string (dpi, "_Sat ");
4239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Don't print "int _Accum".  */
4240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (dc->u.s_fixed.length->u.s_builtin.type
4241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  != &cplus_demangle_builtin_types['i'-'a'])
4242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
4243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_comp (dpi, options, dc->u.s_fixed.length);
4244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_append_char (dpi, ' ');
4245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
4246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (dc->u.s_fixed.accum)
4247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_append_string (dpi, "_Accum");
4248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      else
4249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_append_string (dpi, "_Fract");
4250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
4251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_ARGLIST:
4253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
4254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_left (dc) != NULL)
4255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_comp (dpi, options, d_left (dc));
4256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_right (dc) != NULL)
4257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  size_t len;
4259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  unsigned long int flush_count;
4260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  /* Make sure ", " isn't flushed by d_append_string, otherwise
4261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     dpi->len -= 2 wouldn't work.  */
4262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if (dpi->len >= sizeof (dpi->buf) - 2)
4263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_print_flush (dpi);
4264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_string (dpi, ", ");
4265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  len = dpi->len;
4266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  flush_count = dpi->flush_count;
4267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_comp (dpi, options, d_right (dc));
4268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  /* If that didn't print anything (which can happen with empty
4269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     template argument packs), remove the comma and space.  */
4270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if (dpi->flush_count == flush_count && dpi->len == len)
4271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    dpi->len -= 2;
4272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_OPERATOR:
4276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
4277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	char c;
4278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_string (dpi, "operator");
4280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	c = dc->u.s_operator.op->name[0];
4281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (IS_LOWER (c))
4282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, ' ');
4283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_buffer (dpi, dc->u.s_operator.op->name,
4284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			 dc->u.s_operator.op->len);
4285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return;
4286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
4289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "operator ");
4290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, dc->u.s_extended_operator.name);
4291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CAST:
4294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "operator ");
4295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_cast (dpi, options, dc);
4296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_UNARY:
4299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
4300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  && d_left (dc)->u.s_operator.op->len == 1
4301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  && d_left (dc)->u.s_operator.op->name[0] == '&'
4302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  && d_right (dc)->type == DEMANGLE_COMPONENT_TYPED_NAME
4303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  && d_left (d_right (dc))->type == DEMANGLE_COMPONENT_QUAL_NAME
4304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  && d_right (d_right (dc))->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
4305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
4306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  /* Address of a function (therefore in an expression context) must
4307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     have its argument list suppressed.
4308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     unary operator ... dc
4310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       operator & ... d_left (dc)
4311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       typed name ... d_right (dc)
4312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		 qualified name ... d_left (d_right (dc))
4313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		   <names>
4314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		 function type ... d_right (d_right (dc))
4315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		   argument list
4316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		     <arguments>  */
4317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_expr_op (dpi, options, d_left (dc));
4319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_comp (dpi, options, d_left (d_right (dc)));
4320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  return;
4321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
4322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      else if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
4323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       && d_left (dc)->u.s_operator.op->len == 1
4324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       && d_left (dc)->u.s_operator.op->name[0] == '&'
4325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       && d_right (dc)->type == DEMANGLE_COMPONENT_QUAL_NAME)
4326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
4327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  /* Keep also already processed variant without the argument list.
4328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     unary operator ... dc
4330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       operator & ... d_left (dc)
4331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       qualified name ... d_right (dc)
4332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		 <names>  */
4333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_expr_op (dpi, options, d_left (dc));
4335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_comp (dpi, options, d_right (dc));
4336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  return;
4337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
4338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      else if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST)
4339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_expr_op (dpi, options, d_left (dc));
4340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
4341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, '(');
4343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_cast (dpi, options, d_left (dc));
4344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, ')');
4345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_subexpr (dpi, options, d_right (dc));
4347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY:
4350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_right (dc)->type != DEMANGLE_COMPONENT_BINARY_ARGS)
4351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_print_error (dpi);
4353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return;
4354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We wrap an expression which uses the greater-than operator in
4357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 an extra layer of parens so that it does not get confused
4358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 with the '>' which ends the template parameters.  */
4359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
4360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && d_left (dc)->u.s_operator.op->len == 1
4361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && d_left (dc)->u.s_operator.op->name[0] == '>')
4362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '(');
4363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") == 0
4365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          && d_left (d_right (dc))->type == DEMANGLE_COMPONENT_TYPED_NAME)
4366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
4367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  /* Function call used in an expression should not have printed types
4368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     of the function arguments.  Values of the function arguments still
4369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	     get printed below.  */
4370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  const struct demangle_component *func = d_left (d_right (dc));
4372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if (d_right (func)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
4374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_print_error (dpi);
4375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_subexpr (dpi, options, d_left (func));
4376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
4377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      else
4378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_subexpr (dpi, options, d_left (d_right (dc)));
4379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (strcmp (d_left (dc)->u.s_operator.op->code, "ix") == 0)
4380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
4381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_append_char (dpi, '[');
4382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_comp (dpi, options, d_right (d_right (dc)));
4383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_append_char (dpi, ']');
4384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
4385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      else
4386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
4387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0)
4388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_print_expr_op (dpi, options, d_left (dc));
4389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_print_subexpr (dpi, options, d_right (d_right (dc)));
4390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
4391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
4393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && d_left (dc)->u.s_operator.op->len == 1
4394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && d_left (dc)->u.s_operator.op->name[0] == '>')
4395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ')');
4396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_BINARY_ARGS:
4400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We should only see this as part of DEMANGLE_COMPONENT_BINARY.  */
4401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
4402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY:
4405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_right (dc)->type != DEMANGLE_COMPONENT_TRINARY_ARG1
4406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  || d_right (d_right (dc))->type != DEMANGLE_COMPONENT_TRINARY_ARG2)
4407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_print_error (dpi);
4409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  return;
4410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_subexpr (dpi, options, d_left (d_right (dc)));
4412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_expr_op (dpi, options, d_left (dc));
4413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_subexpr (dpi, options, d_left (d_right (d_right (dc))));
4414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, " : ");
4415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_subexpr (dpi, options, d_right (d_right (d_right (dc))));
4416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG1:
4419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TRINARY_ARG2:
4420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We should only see these are part of DEMANGLE_COMPONENT_TRINARY.  */
4421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
4422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL:
4425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_LITERAL_NEG:
4426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
4427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	enum d_builtin_type_print tp;
4428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* For some builtin types, produce simpler output.  */
4430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	tp = D_PRINT_DEFAULT;
4431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (d_left (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)
4432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
4433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    tp = d_left (dc)->u.s_builtin.type->print;
4434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    switch (tp)
4435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      {
4436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_INT:
4437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_UNSIGNED:
4438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_LONG:
4439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_UNSIGNED_LONG:
4440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_LONG_LONG:
4441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_UNSIGNED_LONG_LONG:
4442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME)
4443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
4444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
4445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      d_append_char (dpi, '-');
4446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng		    d_print_comp (dpi, options, d_right (dc));
4447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    switch (tp)
4448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      {
4449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      default:
4450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
4451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_UNSIGNED:
4452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_char (dpi, 'u');
4453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
4454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_LONG:
4455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_char (dpi, 'l');
4456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
4457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_UNSIGNED_LONG:
4458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "ul");
4459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
4460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_LONG_LONG:
4461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "ll");
4462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
4463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case D_PRINT_UNSIGNED_LONG_LONG:
4464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "ull");
4465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
4466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      }
4467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    return;
4468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
4469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
4470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      case D_PRINT_BOOL:
4472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME
4473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    && d_right (dc)->u.s_name.len == 1
4474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    && dc->type == DEMANGLE_COMPONENT_LITERAL)
4475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  {
4476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		    switch (d_right (dc)->u.s_name.s[0])
4477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      {
4478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case '0':
4479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "false");
4480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			return;
4481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      case '1':
4482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			d_append_string (dpi, "true");
4483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			return;
4484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      default:
4485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			break;
4486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		      }
4487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  }
4488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
4489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      default:
4491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
4492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      }
4493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
4494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '(');
4496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_comp (dpi, options, d_left (dc));
4497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ')');
4498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
4499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, '-');
4500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (tp == D_PRINT_FLOAT)
4501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, '[');
4502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_print_comp (dpi, options, d_right (dc));
4503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (tp == D_PRINT_FLOAT)
4504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  d_append_char (dpi, ']');
4505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_NUMBER:
4509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_num (dpi, dc->u.s_number.number);
4510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
4511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_JAVA_RESOURCE:
4513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "java resource ");
4514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
4515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPOUND_NAME:
4518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
4519663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_right (dc));
4520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CHARACTER:
4523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, dc->u.s_character.character);
4524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_DECLTYPE:
4527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "decltype (");
4528663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
4529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, ')');
4530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PACK_EXPANSION:
4533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
4534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	int len;
4535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int i;
4536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	struct demangle_component *a = d_find_pack (dpi, d_left (dc));
4537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	if (a == NULL)
4538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  {
4539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    /* d_find_pack won't find anything if the only packs involved
4540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       in this expansion are function parameter packs; in that
4541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	       case, just print the pattern and "...".  */
4542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_print_subexpr (dpi, options, d_left (dc));
4543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_append_string (dpi, "...");
4544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    return;
4545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  }
4546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	len = d_pack_length (a);
4548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_left (dc);
4549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	for (i = 0; i < len; ++i)
4550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
4551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dpi->pack_index = i;
4552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_print_comp (dpi, options, dc);
4553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    if (i < len-1)
4554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_string (dpi, ", ");
4555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
4556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_FUNCTION_PARAM:
4560663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      {
4561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	long num = dc->u.s_number.number;
4562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	if (num == 0)
4563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_append_string (dpi, "this");
4564663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	else
4565663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  {
4566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_append_string (dpi, "{parm#");
4567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_append_num (dpi, num);
4568663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	    d_append_char (dpi, '}');
4569663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  }
4570663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
4571663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
4572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4573663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
4574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, "global constructors keyed to ");
4575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, dc->u.s_binary.left);
4576663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
4577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4578663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
4579663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, "global destructors keyed to ");
4580663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, dc->u.s_binary.left);
4581663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
4582663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4583663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_LAMBDA:
4584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, "{lambda(");
4585663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, dc->u.s_unary_num.sub);
4586663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, ")#");
4587663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_num (dpi, dc->u.s_unary_num.num + 1);
4588663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_char (dpi, '}');
4589663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
4590663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4591663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_UNNAMED_TYPE:
4592663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, "{unnamed type#");
4593663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_num (dpi, dc->u.s_number.number + 1);
4594663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_char (dpi, '}');
4595663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
4596663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4597663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_CLONE:
4598663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (dc));
4599663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, " [clone ");
4600663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_right (dc));
4601663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_char (dpi, ']');
4602663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
4603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
4605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_print_error (dpi);
4606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a Java dentifier.  For Java we try to handle encoded extended
4611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Unicode characters.  The C++ ABI doesn't mention Unicode encoding,
4612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   so we don't it for C++.  Characters are encoded as
4613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __U<hex-char>+_.  */
4614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_print_java_identifier (struct d_print_info *dpi, const char *name, int len)
4617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *p;
4619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const char *end;
4620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  end = name + len;
4622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (p = name; p < end; ++p)
4623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (end - p > 3
4625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && p[0] == '_'
4626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && p[1] == '_'
4627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && p[2] == 'U')
4628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  unsigned long c;
4630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  const char *q;
4631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  c = 0;
4633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  for (q = p + 3; q < end; ++q)
4634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
4635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      int dig;
4636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (IS_DIGIT (*q))
4638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dig = *q - '0';
4639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else if (*q >= 'A' && *q <= 'F')
4640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dig = *q - 'A' + 10;
4641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else if (*q >= 'a' && *q <= 'f')
4642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		dig = *q - 'a' + 10;
4643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
4644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
4645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = c * 16 + dig;
4647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* If the Unicode character is larger than 256, we don't try
4649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     to deal with it here.  FIXME.  */
4650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (q < end && *q == '_' && c < 256)
4651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
4652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      d_append_char (dpi, c);
4653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      p = q;
4654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      continue;
4655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, *p);
4659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a list of modifiers.  SUFFIX is 1 if we are printing
4663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   qualifiers on this after printing a function.  */
4664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4666663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_mod_list (struct d_print_info *dpi, int options,
4667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  struct d_print_mod *mods, int suffix)
4668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_template *hold_dpt;
4670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mods == NULL || d_print_saw_error (dpi))
4672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return;
4673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mods->printed
4675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      || (! suffix
4676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS
4677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS
4678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS)))
4679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_mod_list (dpi, options, mods->next, suffix);
4681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  mods->printed = 1;
4685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hold_dpt = dpi->templates;
4687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->templates = mods->templates;
4688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mods->mod->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
4690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4691663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_function_type (dpi, options, mods->mod, mods->next);
4692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = hold_dpt;
4693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (mods->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
4696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_array_type (dpi, options, mods->mod, mods->next);
4698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = hold_dpt;
4699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (mods->mod->type == DEMANGLE_COMPONENT_LOCAL_NAME)
4702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct d_print_mod *hold_modifiers;
4704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct demangle_component *dc;
4705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* When this is on the modifier stack, we have pulled any
4707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 qualifiers off the right argument already.  Otherwise, we
4708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 print it as usual, but don't let the left argument see any
4709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 modifiers.  */
4710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      hold_modifiers = dpi->modifiers;
4712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->modifiers = NULL;
4713663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (mods->mod));
4714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->modifiers = hold_modifiers;
4715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4716663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if ((options & DMGL_JAVA) == 0)
4717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_string (dpi, "::");
4718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
4719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '.');
4720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = d_right (mods->mod);
4722663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4723663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (dc->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
4724663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	{
4725663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_append_string (dpi, "{default arg#");
4726663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_append_num (dpi, dc->u.s_unary_num.num + 1);
4727663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  d_append_string (dpi, "}::");
4728663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	  dc = dc->u.s_unary_num.sub;
4729663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	}
4730663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
4732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
4733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     || dc->type == DEMANGLE_COMPONENT_CONST_THIS)
4734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	dc = d_left (dc);
4735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4736663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, dc);
4737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = hold_dpt;
4739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4742663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_print_mod (dpi, options, mods->mod);
4743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->templates = hold_dpt;
4745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4746663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_print_mod_list (dpi, options, mods->next, suffix);
4747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a modifier.  */
4750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_mod (struct d_print_info *dpi, int options,
4753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             const struct demangle_component *mod)
4754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  switch (mod->type)
4756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT:
4758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RESTRICT_THIS:
4759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, " restrict");
4760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE:
4762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VOLATILE_THIS:
4763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, " volatile");
4764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST:
4766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_CONST_THIS:
4767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, " const");
4768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
4770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, ' ');
4771663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_right (mod));
4772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_POINTER:
4774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* There is no pointer symbol in Java.  */
4775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if ((options & DMGL_JAVA) == 0)
4776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, '*');
4777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_REFERENCE:
4779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '&');
4780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
4782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "&&");
4783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_COMPLEX:
4785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "complex ");
4786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_IMAGINARY:
4788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "imaginary ");
4789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_PTRMEM_TYPE:
4791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_last_char (dpi) != '(')
4792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ' ');
4793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (mod));
4794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_string (dpi, "::*");
4795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    case DEMANGLE_COMPONENT_TYPED_NAME:
4797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (mod));
4798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      return;
4799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    case DEMANGLE_COMPONENT_VECTOR_TYPE:
4800663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_string (dpi, " __vector(");
4801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (mod));
4802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_append_char (dpi, ')');
4803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4804663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
4805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    default:
4806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Otherwise, we have something that won't go back on the
4807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 modifier stack, so we can just print it.  */
4808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, mod);
4809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
4810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a function type, except for the return type.  */
4814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_function_type (struct d_print_info *dpi, int options,
4817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       const struct demangle_component *dc,
4818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       struct d_print_mod *mods)
4819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int need_paren;
4821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int need_space;
4822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_mod *p;
4823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_print_mod *hold_modifiers;
4824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  need_paren = 0;
4826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  need_space = 0;
4827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (p = mods; p != NULL; p = p->next)
4828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (p->printed)
4830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	break;
4831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (p->mod->type)
4833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_POINTER:
4835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_REFERENCE:
4836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
4837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  need_paren = 1;
4838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_RESTRICT:
4840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_VOLATILE:
4841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_CONST:
4842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
4843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_COMPLEX:
4844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_IMAGINARY:
4845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_PTRMEM_TYPE:
4846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  need_space = 1;
4847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  need_paren = 1;
4848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_RESTRICT_THIS:
4850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_VOLATILE_THIS:
4851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case DEMANGLE_COMPONENT_CONST_THIS:
4852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	default:
4854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
4855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (need_paren)
4857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	break;
4858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (need_paren)
4861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (! need_space)
4863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (d_last_char (dpi) != '('
4865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      && d_last_char (dpi) != '*')
4866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    need_space = 1;
4867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (need_space && d_last_char (dpi) != ' ')
4869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ' ');
4870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '(');
4871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hold_modifiers = dpi->modifiers;
4874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->modifiers = NULL;
4875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_print_mod_list (dpi, options, mods, 0);
4877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (need_paren)
4879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, ')');
4880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_char (dpi, '(');
4882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_right (dc) != NULL)
4884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    d_print_comp (dpi, options, d_right (dc));
4885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_char (dpi, ')');
4887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  d_print_mod_list (dpi, options, mods, 1);
4889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  dpi->modifiers = hold_modifiers;
4891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print an array type, except for the element type.  */
4894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_array_type (struct d_print_info *dpi, int options,
4897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    const struct demangle_component *dc,
4898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    struct d_print_mod *mods)
4899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int need_space;
4901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  need_space = 1;
4903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mods != NULL)
4904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int need_paren;
4906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct d_print_mod *p;
4907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      need_paren = 0;
4909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (p = mods; p != NULL; p = p->next)
4910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
4911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (! p->printed)
4912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
4913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (p->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
4914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
4915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  need_space = 0;
4916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  break;
4917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
4918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
4919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
4920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  need_paren = 1;
4921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  need_space = 1;
4922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  break;
4923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
4924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
4925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
4926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (need_paren)
4928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_string (dpi, " (");
4929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4930663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_mod_list (dpi, options, mods, 0);
4931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (need_paren)
4933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ')');
4934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
4935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (need_space)
4937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_char (dpi, ' ');
4938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_char (dpi, '[');
4940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_left (dc) != NULL)
4942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    d_print_comp (dpi, options, d_left (dc));
4943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_append_char (dpi, ']');
4945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print an operator in an expression.  */
4948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_expr_op (struct d_print_info *dpi, int options,
4951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct demangle_component *dc)
4952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (dc->type == DEMANGLE_COMPONENT_OPERATOR)
4954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_append_buffer (dpi, dc->u.s_operator.op->name,
4955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		     dc->u.s_operator.op->len);
4956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
4957663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    d_print_comp (dpi, options, dc);
4958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a cast.  */
4961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
4963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengd_print_cast (struct d_print_info *dpi, int options,
4964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              const struct demangle_component *dc)
4965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE)
4967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    d_print_comp (dpi, options, d_left (dc));
4968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
4969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
4970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct d_print_mod *hold_dpm;
4971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct d_print_template dpt;
4972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* It appears that for a templated cast operator, we need to put
4974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 the template parameters in scope for the operator name, but
4975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 not for the parameters.  The effect is that we need to handle
4976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 the template printing here.  */
4977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      hold_dpm = dpi->modifiers;
4979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->modifiers = NULL;
4980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpt.next = dpi->templates;
4982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = &dpt;
4983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpt.template_decl = d_left (dc);
4984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_left (d_left (dc)));
4986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->templates = dpt.next;
4988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_last_char (dpi) == '<')
4990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ' ');
4991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '<');
4992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      d_print_comp (dpi, options, d_right (d_left (dc)));
4993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Avoid generating two consecutive '>' characters, to avoid
4994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 the C++ syntactic ambiguity.  */
4995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d_last_char (dpi) == '>')
4996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	d_append_char (dpi, ' ');
4997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_append_char (dpi, '>');
4998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dpi->modifiers = hold_dpm;
5000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialize the information structure we use to pass around
5004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   information.  */
5005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCP_STATIC_IF_GLIBCPP_V3
5007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid
5008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_init_info (const char *mangled, int options, size_t len,
5009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          struct d_info *di)
5010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->s = mangled;
5012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->send = mangled + len;
5013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->options = options;
5014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->n = mangled;
5016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* We can not need more components than twice the number of chars in
5018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     the mangled string.  Most components correspond directly to
5019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     chars, but the ARGLIST types are exceptions.  */
5020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->num_comps = 2 * len;
5021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->next_comp = 0;
5022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Similarly, we can not need more substitutions than there are
5024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     chars in the mangled string.  */
5025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->num_subs = len;
5026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->next_sub = 0;
5027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->did_subs = 0;
5028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->last_name = NULL;
5030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  di->expansion = 0;
5032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Internal implementation for the demangler.  If MANGLED is a g++ v3 ABI
5035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mangled name, return strings in repeated callback giving the demangled
5036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name.  OPTIONS is the usual libiberty demangler options.  On success,
5037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this returns 1.  On failure, returns 0.  */
5038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
5040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_demangle_callback (const char *mangled, int options,
5041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     demangle_callbackref callback, void *opaque)
5042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  enum
5044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    {
5045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      DCT_TYPE,
5046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      DCT_MANGLED,
5047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      DCT_GLOBAL_CTORS,
5048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      DCT_GLOBAL_DTORS
5049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    }
5050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  type;
5051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_info di;
5052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *dc;
5053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int status;
5054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mangled[0] == '_' && mangled[1] == 'Z')
5056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    type = DCT_MANGLED;
5057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else if (strncmp (mangled, "_GLOBAL_", 8) == 0
5058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   && (mangled[8] == '.' || mangled[8] == '_' || mangled[8] == '$')
5059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   && (mangled[9] == 'D' || mangled[9] == 'I')
5060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   && mangled[10] == '_')
5061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    type = mangled[9] == 'I' ? DCT_GLOBAL_CTORS : DCT_GLOBAL_DTORS;
5062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
5063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((options & DMGL_TYPES) == 0)
5065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return 0;
5066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      type = DCT_TYPE;
5067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  cplus_demangle_init_info (mangled, options, strlen (mangled), &di);
5070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  {
5072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef CP_DYNAMIC_ARRAYS
5073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __extension__ struct demangle_component comps[di.num_comps];
5074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __extension__ struct demangle_component *subs[di.num_subs];
5075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.comps = comps;
5077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.subs = subs;
5078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
5079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.comps = alloca (di.num_comps * sizeof (*di.comps));
5080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.subs = alloca (di.num_subs * sizeof (*di.subs));
5081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
5082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    switch (type)
5084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      {
5085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case DCT_TYPE:
5086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	dc = cplus_demangle_type (&di);
5087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	break;
5088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case DCT_MANGLED:
5089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	dc = cplus_demangle_mangled_name (&di, 1);
5090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	break;
5091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case DCT_GLOBAL_CTORS:
5092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      case DCT_GLOBAL_DTORS:
5093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_advance (&di, 11);
5094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	dc = d_make_comp (&di,
5095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng			  (type == DCT_GLOBAL_CTORS
5096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng			   ? DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS
5097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng			   : DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS),
5098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng			  d_make_demangle_mangled_name (&di, d_str (&di)),
5099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng			  NULL);
5100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	d_advance (&di, strlen (d_str (&di)));
5101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng	break;
5102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
5103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    /* If DMGL_PARAMS is set, then if we didn't consume the entire
5105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       mangled string, then we didn't successfully demangle it.  If
5106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       DMGL_PARAMS is not set, we didn't look at the trailing
5107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       parameters.  */
5108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (((options & DMGL_PARAMS) != 0) && d_peek_char (&di) != '\0')
5109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dc = NULL;
5110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef CP_DEMANGLE_DEBUG
5112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    d_dump (dc, 0);
5113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
5114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    status = (dc != NULL)
5116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             ? cplus_demangle_print_callback (options, dc, callback, opaque)
5117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             : 0;
5118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
5119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return status;
5121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Entry point for the demangler.  If MANGLED is a g++ v3 ABI mangled
5124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name, return a buffer allocated with malloc holding the demangled
5125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name.  OPTIONS is the usual libiberty demangler options.  On
5126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   success, this sets *PALC to the allocated size of the returned
5127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   buffer.  On failure, this sets *PALC to 0 for a bad name, or 1 for
5128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a memory allocation failure, and returns NULL.  */
5129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic char *
5131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownd_demangle (const char *mangled, int options, size_t *palc)
5132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_growable_string dgs;
5134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int status;
5135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  d_growable_string_init (&dgs, 0);
5137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  status = d_demangle_callback (mangled, options,
5139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                d_growable_string_callback_adapter, &dgs);
5140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (status == 0)
5141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      free (dgs.buf);
5143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *palc = 0;
5144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
5145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng  *palc = dgs.allocation_failure ? 1 : dgs.alc;
5148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dgs.buf;
5149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
5152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern char *__cxa_demangle (const char *, char *, size_t *, int *);
5154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ia64 ABI-mandated entry point in the C++ runtime library for
5156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   performing demangling.  MANGLED_NAME is a NUL-terminated character
5157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   string containing the name to be demangled.
5158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OUTPUT_BUFFER is a region of memory, allocated with malloc, of
5160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *LENGTH bytes, into which the demangled name is stored.  If
5161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OUTPUT_BUFFER is not long enough, it is expanded using realloc.
5162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
5163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   is placed in a region of memory allocated with malloc.
5164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   If LENGTH is non-NULL, the length of the buffer containing the
5166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   demangled name, is placed in *LENGTH.
5167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The return value is a pointer to the start of the NUL-terminated
5169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   demangled name, or NULL if the demangling fails.  The caller is
5170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   responsible for deallocating this memory using free.
5171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *STATUS is set to one of the following values:
5173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      0: The demangling operation succeeded.
5174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -1: A memory allocation failure occurred.
5175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
5176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -3: One of the arguments is invalid.
5177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The demangling is performed using the C++ ABI mangling rules, with
5179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GNU extensions.  */
5180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar *
5182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__cxa_demangle (const char *mangled_name, char *output_buffer,
5183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                size_t *length, int *status)
5184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  char *demangled;
5186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t alc;
5187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mangled_name == NULL)
5189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (status != NULL)
5191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	*status = -3;
5192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
5193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (output_buffer != NULL && length == NULL)
5196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (status != NULL)
5198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	*status = -3;
5199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
5200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc);
5203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (demangled == NULL)
5205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (status != NULL)
5207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
5208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (alc == 1)
5209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    *status = -1;
5210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  else
5211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    *status = -2;
5212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
5213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return NULL;
5214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (output_buffer == NULL)
5217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (length != NULL)
5219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	*length = alc;
5220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
5222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (strlen (demangled) < *length)
5224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
5225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  strcpy (output_buffer, demangled);
5226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  free (demangled);
5227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  demangled = output_buffer;
5228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
5229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
5230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
5231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  free (output_buffer);
5232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  *length = alc;
5233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
5234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (status != NULL)
5237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    *status = 0;
5238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return demangled;
5240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern int __gcclibcxx_demangle_callback (const char *,
5243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                          void (*)
5244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                            (const char *, size_t, void *),
5245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                          void *);
5246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Alternative, allocationless entry point in the C++ runtime library
5248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for performing demangling.  MANGLED_NAME is a NUL-terminated character
5249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   string containing the name to be demangled.
5250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CALLBACK is a callback function, called with demangled string
5252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   segments as demangling progresses; it is called at least once,
5253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   but may be called more than once.  OPAQUE is a generalized pointer
5254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   used as a callback argument.
5255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The return code is one of the following values, equivalent to
5257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the STATUS values of __cxa_demangle() (excluding -1, since this
5258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   function performs no memory allocations):
5259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      0: The demangling operation succeeded.
5260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
5261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     -3: One of the arguments is invalid.
5262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The demangling is performed using the C++ ABI mangling rules, with
5264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GNU extensions.  */
5265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
5267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__gcclibcxx_demangle_callback (const char *mangled_name,
5268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               void (*callback) (const char *, size_t, void *),
5269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               void *opaque)
5270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int status;
5272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (mangled_name == NULL || callback == NULL)
5274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return -3;
5275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  status = d_demangle_callback (mangled_name, DMGL_PARAMS | DMGL_TYPES,
5277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                callback, opaque);
5278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (status == 0)
5279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return -2;
5280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 0;
5282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
5285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Entry point for libiberty demangler.  If MANGLED is a g++ v3 ABI
5287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mangled name, return a buffer allocated with malloc holding the
5288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   demangled name.  Otherwise, return NULL.  */
5289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar *
5291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_v3 (const char *mangled, int options)
5292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t alc;
5294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_demangle (mangled, options, &alc);
5296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
5299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncplus_demangle_v3_callback (const char *mangled, int options,
5300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            demangle_callbackref callback, void *opaque)
5301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_demangle_callback (mangled, options, callback, opaque);
5303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Demangle a Java symbol.  Java uses a subset of the V3 ABI C++ mangling
5306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   conventions, but the output formatting is a little different.
5307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This instructs the C++ demangler not to emit pointer characters ("*"), to
5308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   use Java's namespace separator symbol ("." instead of "::"), and to output
5309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   JArray<TYPE> as TYPE[].  */
5310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar *
5312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownjava_demangle_v3 (const char *mangled)
5313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  size_t alc;
5315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_demangle (mangled, DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX, &alc);
5317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
5320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownjava_demangle_v3_callback (const char *mangled,
5321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           demangle_callbackref callback, void *opaque)
5322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return d_demangle_callback (mangled,
5324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX,
5325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              callback, opaque);
5326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
5329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef IN_GLIBCPP_V3
5331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Demangle a string in order to find out whether it is a constructor
5333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   or destructor.  Return non-zero on success.  Set *CTOR_KIND and
5334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *DTOR_KIND appropriately.  */
5335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int
5337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_ctor_or_dtor (const char *mangled,
5338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 enum gnu_v3_ctor_kinds *ctor_kind,
5339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 enum gnu_v3_dtor_kinds *dtor_kind)
5340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct d_info di;
5342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  struct demangle_component *dc;
5343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int ret;
5344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *ctor_kind = (enum gnu_v3_ctor_kinds) 0;
5346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *dtor_kind = (enum gnu_v3_dtor_kinds) 0;
5347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  cplus_demangle_init_info (mangled, DMGL_GNU_V3, strlen (mangled), &di);
5349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  {
5351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef CP_DYNAMIC_ARRAYS
5352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __extension__ struct demangle_component comps[di.num_comps];
5353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    __extension__ struct demangle_component *subs[di.num_subs];
5354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.comps = comps;
5356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.subs = subs;
5357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
5358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.comps = alloca (di.num_comps * sizeof (*di.comps));
5359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    di.subs = alloca (di.num_subs * sizeof (*di.subs));
5360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
5361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    dc = cplus_demangle_mangled_name (&di, 1);
5363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    /* Note that because we did not pass DMGL_PARAMS, we don't expect
5365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       to demangle the entire string.  */
5366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ret = 0;
5368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    while (dc != NULL)
5369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
5370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	switch (dc->type)
5371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  {
5372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  default:
5373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = NULL;
5374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
5375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_TYPED_NAME:
5376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_TEMPLATE:
5377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_RESTRICT_THIS:
5378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_VOLATILE_THIS:
5379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_CONST_THIS:
5380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_left (dc);
5381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
5382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_QUAL_NAME:
5383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_LOCAL_NAME:
5384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = d_right (dc);
5385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
5386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_CTOR:
5387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    *ctor_kind = dc->u.s_ctor.kind;
5388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = 1;
5389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = NULL;
5390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
5391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  case DEMANGLE_COMPONENT_DTOR:
5392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    *dtor_kind = dc->u.s_dtor.kind;
5393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    ret = 1;
5394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    dc = NULL;
5395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    break;
5396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  }
5397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
5398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
5399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ret;
5401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return whether NAME is the mangled form of a g++ V3 ABI constructor
5404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name.  A non-zero return indicates the type of constructor.  */
5405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownenum gnu_v3_ctor_kinds
5407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_gnu_v3_mangled_ctor (const char *name)
5408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  enum gnu_v3_ctor_kinds ctor_kind;
5410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  enum gnu_v3_dtor_kinds dtor_kind;
5411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
5413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return (enum gnu_v3_ctor_kinds) 0;
5414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return ctor_kind;
5415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Return whether NAME is the mangled form of a g++ V3 ABI destructor
5419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   name.  A non-zero return indicates the type of destructor.  */
5420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownenum gnu_v3_dtor_kinds
5422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownis_gnu_v3_mangled_dtor (const char *name)
5423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  enum gnu_v3_ctor_kinds ctor_kind;
5425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  enum gnu_v3_dtor_kinds dtor_kind;
5426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
5428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return (enum gnu_v3_dtor_kinds) 0;
5429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return dtor_kind;
5430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* IN_GLIBCPP_V3 */
5433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef STANDALONE_DEMANGLER
5435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */
5437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "getopt.h"
5438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "dyn-string.h"
5439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */
5440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void print_usage (FILE* fp, int exit_value);
5442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define IS_ALPHA(CHAR)                                                  \
5444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  (((CHAR) >= 'a' && (CHAR) <= 'z')                                     \
5445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
5446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Non-zero if CHAR is a character than can occur in a mangled name.  */
5448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define is_mangled_char(CHAR)                                           \
5449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  (IS_ALPHA (CHAR) || IS_DIGIT (CHAR)                                   \
5450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
5451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The name of this program, as invoked.  */
5453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst char* program_name;
5454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Prints usage summary to FP and then exits with EXIT_VALUE.  */
5456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void
5458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownprint_usage (FILE* fp, int exit_value)
5459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
5461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "Options:\n");
5462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "  -h,--help       Display this message.\n");
5463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "  -p,--no-params  Don't display function parameters\n");
5464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "  -v,--verbose    Produce verbose demanglings.\n");
5465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf (fp, "If names are provided, they are demangled.  Otherwise filters standard input.\n");
5466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  exit (exit_value);
5468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Option specification for getopt_long.  */
5471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const struct option long_options[] =
5472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "help",	 no_argument, NULL, 'h' },
5474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "no-params", no_argument, NULL, 'p' },
5475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { "verbose",   no_argument, NULL, 'v' },
5476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  { NULL,        no_argument, NULL, 0   },
5477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
5478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Main entry for a demangling filter executable.  It will demangle
5480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   its command line arguments, if any.  If none are provided, it will
5481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   filter stdin to stdout, replacing any recognized mangled C++ names
5482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   with their demangled equivalents.  */
5483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint
5485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmain (int argc, char *argv[])
5486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int i;
5488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int opt_char;
5489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int options = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES;
5490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Use the program name of this program, as invoked.  */
5492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  program_name = argv[0];
5493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  /* Parse options.  */
5495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  do
5496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      opt_char = getopt_long (argc, argv, "hpv", long_options, NULL);
5498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (opt_char)
5499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
5500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case '?':  /* Unrecognized option.  */
5501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  print_usage (stderr, 1);
5502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
5503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'h':
5505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  print_usage (stdout, 0);
5506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
5507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'p':
5509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  options &= ~ DMGL_PARAMS;
5510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
5511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	case 'v':
5513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  options |= DMGL_VERBOSE;
5514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  break;
5515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
5516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  while (opt_char != -1);
5518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (optind == argc)
5520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    /* No command line arguments were provided.  Filter stdin.  */
5521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dyn_string_t mangled = dyn_string_new (3);
5523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      char *s;
5524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read all of input.  */
5526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (!feof (stdin))
5527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
5528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  char c;
5529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* Pile characters into mangled until we hit one that can't
5531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     occur in a mangled name.  */
5532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  c = getchar ();
5533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  while (!feof (stdin) && is_mangled_char (c))
5534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
5535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dyn_string_append_char (mangled, c);
5536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (feof (stdin))
5537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		break;
5538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      c = getchar ();
5539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
5540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (dyn_string_length (mangled) > 0)
5542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
5543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef IN_GLIBCPP_V3
5544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      s = __cxa_demangle (dyn_string_buf (mangled), NULL, NULL, NULL);
5545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
5546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      s = cplus_demangle_v3 (dyn_string_buf (mangled), options);
5547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
5548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      if (s != NULL)
5550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
5551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  fputs (s, stdout);
5552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  free (s);
5553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
5554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      else
5555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		{
5556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  /* It might not have been a mangled name.  Print the
5557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		     original text.  */
5558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		  fputs (dyn_string_buf (mangled), stdout);
5559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		}
5560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      dyn_string_clear (mangled);
5562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
5563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* If we haven't hit EOF yet, we've read one character that
5565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	     can't occur in a mangled name, so print it out.  */
5566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (!feof (stdin))
5567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    putchar (c);
5568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
5569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dyn_string_delete (mangled);
5571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
5573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    /* Demangle command line arguments.  */
5574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    {
5575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Loop over command line arguments.  */
5576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = optind; i < argc; ++i)
5577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	{
5578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  char *s;
5579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef IN_GLIBCPP_V3
5580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  int status;
5581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
5582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* Attempt to demangle.  */
5584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef IN_GLIBCPP_V3
5585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  s = __cxa_demangle (argv[i], NULL, NULL, &status);
5586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
5587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  s = cplus_demangle_v3 (argv[i], options);
5588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
5589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  /* If it worked, print the demangled name.  */
5591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  if (s != NULL)
5592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
5593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      printf ("%s\n", s);
5594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      free (s);
5595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
5596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	  else
5597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    {
5598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef IN_GLIBCPP_V3
5599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      fprintf (stderr, "Failed: %s (status %d)\n", argv[i], status);
5600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
5601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	      fprintf (stderr, "Failed: %s\n", argv[i]);
5602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
5603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    }
5604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
5605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
5606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 0;
5608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* STANDALONE_DEMANGLER */
5611