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