15796c8dcSSimon Schubert /* Demangler for g++ V3 ABI.
2a45ae5f8SJohn Marino    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
35796c8dcSSimon Schubert    Free Software Foundation, Inc.
45796c8dcSSimon Schubert    Written by Ian Lance Taylor <ian@wasabisystems.com>.
55796c8dcSSimon Schubert 
65796c8dcSSimon Schubert    This file is part of the libiberty library, which is part of GCC.
75796c8dcSSimon Schubert 
85796c8dcSSimon Schubert    This file is free software; you can redistribute it and/or modify
95796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
105796c8dcSSimon Schubert    the Free Software Foundation; either version 2 of the License, or
115796c8dcSSimon Schubert    (at your option) any later version.
125796c8dcSSimon Schubert 
135796c8dcSSimon Schubert    In addition to the permissions in the GNU General Public License, the
145796c8dcSSimon Schubert    Free Software Foundation gives you unlimited permission to link the
155796c8dcSSimon Schubert    compiled version of this file into combinations with other programs,
165796c8dcSSimon Schubert    and to distribute those combinations without any restriction coming
175796c8dcSSimon Schubert    from the use of this file.  (The General Public License restrictions
185796c8dcSSimon Schubert    do apply in other respects; for example, they cover modification of
195796c8dcSSimon Schubert    the file, and distribution when not linked into a combined
205796c8dcSSimon Schubert    executable.)
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
235796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
245796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
255796c8dcSSimon Schubert    GNU General Public License for more details.
265796c8dcSSimon Schubert 
275796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
285796c8dcSSimon Schubert    along with this program; if not, write to the Free Software
295796c8dcSSimon Schubert    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
305796c8dcSSimon Schubert */
315796c8dcSSimon Schubert 
325796c8dcSSimon Schubert /* This code implements a demangler for the g++ V3 ABI.  The ABI is
335796c8dcSSimon Schubert    described on this web page:
345796c8dcSSimon Schubert        http://www.codesourcery.com/cxx-abi/abi.html#mangling
355796c8dcSSimon Schubert 
365796c8dcSSimon Schubert    This code was written while looking at the demangler written by
375796c8dcSSimon Schubert    Alex Samuel <samuel@codesourcery.com>.
385796c8dcSSimon Schubert 
395796c8dcSSimon Schubert    This code first pulls the mangled name apart into a list of
405796c8dcSSimon Schubert    components, and then walks the list generating the demangled
415796c8dcSSimon Schubert    name.
425796c8dcSSimon Schubert 
435796c8dcSSimon Schubert    This file will normally define the following functions, q.v.:
445796c8dcSSimon Schubert       char *cplus_demangle_v3(const char *mangled, int options)
455796c8dcSSimon Schubert       char *java_demangle_v3(const char *mangled)
465796c8dcSSimon Schubert       int cplus_demangle_v3_callback(const char *mangled, int options,
475796c8dcSSimon Schubert                                      demangle_callbackref callback)
485796c8dcSSimon Schubert       int java_demangle_v3_callback(const char *mangled,
495796c8dcSSimon Schubert                                     demangle_callbackref callback)
505796c8dcSSimon Schubert       enum gnu_v3_ctor_kinds is_gnu_v3_mangled_ctor (const char *name)
515796c8dcSSimon Schubert       enum gnu_v3_dtor_kinds is_gnu_v3_mangled_dtor (const char *name)
525796c8dcSSimon Schubert 
535796c8dcSSimon Schubert    Also, the interface to the component list is public, and defined in
545796c8dcSSimon Schubert    demangle.h.  The interface consists of these types, which are
555796c8dcSSimon Schubert    defined in demangle.h:
565796c8dcSSimon Schubert       enum demangle_component_type
575796c8dcSSimon Schubert       struct demangle_component
585796c8dcSSimon Schubert       demangle_callbackref
595796c8dcSSimon Schubert    and these functions defined in this file:
605796c8dcSSimon Schubert       cplus_demangle_fill_name
615796c8dcSSimon Schubert       cplus_demangle_fill_extended_operator
625796c8dcSSimon Schubert       cplus_demangle_fill_ctor
635796c8dcSSimon Schubert       cplus_demangle_fill_dtor
645796c8dcSSimon Schubert       cplus_demangle_print
655796c8dcSSimon Schubert       cplus_demangle_print_callback
665796c8dcSSimon Schubert    and other functions defined in the file cp-demint.c.
675796c8dcSSimon Schubert 
685796c8dcSSimon Schubert    This file also defines some other functions and variables which are
695796c8dcSSimon Schubert    only to be used by the file cp-demint.c.
705796c8dcSSimon Schubert 
715796c8dcSSimon Schubert    Preprocessor macros you can define while compiling this file:
725796c8dcSSimon Schubert 
735796c8dcSSimon Schubert    IN_LIBGCC2
745796c8dcSSimon Schubert       If defined, this file defines the following functions, q.v.:
755796c8dcSSimon Schubert          char *__cxa_demangle (const char *mangled, char *buf, size_t *len,
765796c8dcSSimon Schubert                                int *status)
775796c8dcSSimon Schubert          int __gcclibcxx_demangle_callback (const char *,
785796c8dcSSimon Schubert                                             void (*)
795796c8dcSSimon Schubert                                               (const char *, size_t, void *),
805796c8dcSSimon Schubert                                             void *)
815796c8dcSSimon Schubert       instead of cplus_demangle_v3[_callback]() and
825796c8dcSSimon Schubert       java_demangle_v3[_callback]().
835796c8dcSSimon Schubert 
845796c8dcSSimon Schubert    IN_GLIBCPP_V3
855796c8dcSSimon Schubert       If defined, this file defines only __cxa_demangle() and
865796c8dcSSimon Schubert       __gcclibcxx_demangle_callback(), and no other publically visible
875796c8dcSSimon Schubert       functions or variables.
885796c8dcSSimon Schubert 
895796c8dcSSimon Schubert    STANDALONE_DEMANGLER
905796c8dcSSimon Schubert       If defined, this file defines a main() function which demangles
915796c8dcSSimon Schubert       any arguments, or, if none, demangles stdin.
925796c8dcSSimon Schubert 
935796c8dcSSimon Schubert    CP_DEMANGLE_DEBUG
945796c8dcSSimon Schubert       If defined, turns on debugging mode, which prints information on
955796c8dcSSimon Schubert       stdout about the mangled string.  This is not generally useful.
965796c8dcSSimon Schubert */
975796c8dcSSimon Schubert 
985796c8dcSSimon Schubert #if defined (_AIX) && !defined (__GNUC__)
995796c8dcSSimon Schubert  #pragma alloca
1005796c8dcSSimon Schubert #endif
1015796c8dcSSimon Schubert 
1025796c8dcSSimon Schubert #ifdef HAVE_CONFIG_H
1035796c8dcSSimon Schubert #include "config.h"
1045796c8dcSSimon Schubert #endif
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert #include <stdio.h>
1075796c8dcSSimon Schubert 
1085796c8dcSSimon Schubert #ifdef HAVE_STDLIB_H
1095796c8dcSSimon Schubert #include <stdlib.h>
1105796c8dcSSimon Schubert #endif
1115796c8dcSSimon Schubert #ifdef HAVE_STRING_H
1125796c8dcSSimon Schubert #include <string.h>
1135796c8dcSSimon Schubert #endif
1145796c8dcSSimon Schubert 
1155796c8dcSSimon Schubert #ifdef HAVE_ALLOCA_H
1165796c8dcSSimon Schubert # include <alloca.h>
1175796c8dcSSimon Schubert #else
1185796c8dcSSimon Schubert # ifndef alloca
1195796c8dcSSimon Schubert #  ifdef __GNUC__
1205796c8dcSSimon Schubert #   define alloca __builtin_alloca
1215796c8dcSSimon Schubert #  else
1225796c8dcSSimon Schubert extern char *alloca ();
1235796c8dcSSimon Schubert #  endif /* __GNUC__ */
1245796c8dcSSimon Schubert # endif /* alloca */
1255796c8dcSSimon Schubert #endif /* HAVE_ALLOCA_H */
1265796c8dcSSimon Schubert 
1275796c8dcSSimon Schubert #include "ansidecl.h"
1285796c8dcSSimon Schubert #include "libiberty.h"
1295796c8dcSSimon Schubert #include "demangle.h"
1305796c8dcSSimon Schubert #include "cp-demangle.h"
1315796c8dcSSimon Schubert 
1325796c8dcSSimon Schubert /* If IN_GLIBCPP_V3 is defined, some functions are made static.  We
1335796c8dcSSimon Schubert    also rename them via #define to avoid compiler errors when the
1345796c8dcSSimon Schubert    static definition conflicts with the extern declaration in a header
1355796c8dcSSimon Schubert    file.  */
1365796c8dcSSimon Schubert #ifdef IN_GLIBCPP_V3
1375796c8dcSSimon Schubert 
1385796c8dcSSimon Schubert #define CP_STATIC_IF_GLIBCPP_V3 static
1395796c8dcSSimon Schubert 
1405796c8dcSSimon Schubert #define cplus_demangle_fill_name d_fill_name
1415796c8dcSSimon Schubert static int d_fill_name (struct demangle_component *, const char *, int);
1425796c8dcSSimon Schubert 
1435796c8dcSSimon Schubert #define cplus_demangle_fill_extended_operator d_fill_extended_operator
1445796c8dcSSimon Schubert static int
1455796c8dcSSimon Schubert d_fill_extended_operator (struct demangle_component *, int,
1465796c8dcSSimon Schubert                           struct demangle_component *);
1475796c8dcSSimon Schubert 
1485796c8dcSSimon Schubert #define cplus_demangle_fill_ctor d_fill_ctor
1495796c8dcSSimon Schubert static int
1505796c8dcSSimon Schubert d_fill_ctor (struct demangle_component *, enum gnu_v3_ctor_kinds,
1515796c8dcSSimon Schubert              struct demangle_component *);
1525796c8dcSSimon Schubert 
1535796c8dcSSimon Schubert #define cplus_demangle_fill_dtor d_fill_dtor
1545796c8dcSSimon Schubert static int
1555796c8dcSSimon Schubert d_fill_dtor (struct demangle_component *, enum gnu_v3_dtor_kinds,
1565796c8dcSSimon Schubert              struct demangle_component *);
1575796c8dcSSimon Schubert 
1585796c8dcSSimon Schubert #define cplus_demangle_mangled_name d_mangled_name
1595796c8dcSSimon Schubert static struct demangle_component *d_mangled_name (struct d_info *, int);
1605796c8dcSSimon Schubert 
1615796c8dcSSimon Schubert #define cplus_demangle_type d_type
1625796c8dcSSimon Schubert static struct demangle_component *d_type (struct d_info *);
1635796c8dcSSimon Schubert 
1645796c8dcSSimon Schubert #define cplus_demangle_print d_print
1655796c8dcSSimon Schubert static char *d_print (int, const struct demangle_component *, int, size_t *);
1665796c8dcSSimon Schubert 
1675796c8dcSSimon Schubert #define cplus_demangle_print_callback d_print_callback
1685796c8dcSSimon Schubert static int d_print_callback (int, const struct demangle_component *,
1695796c8dcSSimon Schubert                              demangle_callbackref, void *);
1705796c8dcSSimon Schubert 
1715796c8dcSSimon Schubert #define cplus_demangle_init_info d_init_info
1725796c8dcSSimon Schubert static void d_init_info (const char *, int, size_t, struct d_info *);
1735796c8dcSSimon Schubert 
1745796c8dcSSimon Schubert #else /* ! defined(IN_GLIBCPP_V3) */
1755796c8dcSSimon Schubert #define CP_STATIC_IF_GLIBCPP_V3
1765796c8dcSSimon Schubert #endif /* ! defined(IN_GLIBCPP_V3) */
1775796c8dcSSimon Schubert 
1785796c8dcSSimon Schubert /* See if the compiler supports dynamic arrays.  */
1795796c8dcSSimon Schubert 
1805796c8dcSSimon Schubert #ifdef __GNUC__
1815796c8dcSSimon Schubert #define CP_DYNAMIC_ARRAYS
1825796c8dcSSimon Schubert #else
1835796c8dcSSimon Schubert #ifdef __STDC__
1845796c8dcSSimon Schubert #ifdef __STDC_VERSION__
1855796c8dcSSimon Schubert #if __STDC_VERSION__ >= 199901L
1865796c8dcSSimon Schubert #define CP_DYNAMIC_ARRAYS
1875796c8dcSSimon Schubert #endif /* __STDC__VERSION >= 199901L */
1885796c8dcSSimon Schubert #endif /* defined (__STDC_VERSION__) */
1895796c8dcSSimon Schubert #endif /* defined (__STDC__) */
1905796c8dcSSimon Schubert #endif /* ! defined (__GNUC__) */
1915796c8dcSSimon Schubert 
1925796c8dcSSimon Schubert /* We avoid pulling in the ctype tables, to prevent pulling in
1935796c8dcSSimon Schubert    additional unresolved symbols when this code is used in a library.
1945796c8dcSSimon Schubert    FIXME: Is this really a valid reason?  This comes from the original
1955796c8dcSSimon Schubert    V3 demangler code.
1965796c8dcSSimon Schubert 
1975796c8dcSSimon Schubert    As of this writing this file has the following undefined references
1985796c8dcSSimon Schubert    when compiled with -DIN_GLIBCPP_V3: realloc, free, memcpy, strcpy,
1995796c8dcSSimon Schubert    strcat, strlen.  */
2005796c8dcSSimon Schubert 
2015796c8dcSSimon Schubert #define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
2025796c8dcSSimon Schubert #define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
2035796c8dcSSimon Schubert #define IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')
2045796c8dcSSimon Schubert 
2055796c8dcSSimon Schubert /* The prefix prepended by GCC to an identifier represnting the
2065796c8dcSSimon Schubert    anonymous namespace.  */
2075796c8dcSSimon Schubert #define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
2085796c8dcSSimon Schubert #define ANONYMOUS_NAMESPACE_PREFIX_LEN \
2095796c8dcSSimon Schubert   (sizeof (ANONYMOUS_NAMESPACE_PREFIX) - 1)
2105796c8dcSSimon Schubert 
2115796c8dcSSimon Schubert /* Information we keep for the standard substitutions.  */
2125796c8dcSSimon Schubert 
2135796c8dcSSimon Schubert struct d_standard_sub_info
2145796c8dcSSimon Schubert {
2155796c8dcSSimon Schubert   /* The code for this substitution.  */
2165796c8dcSSimon Schubert   char code;
2175796c8dcSSimon Schubert   /* The simple string it expands to.  */
2185796c8dcSSimon Schubert   const char *simple_expansion;
2195796c8dcSSimon Schubert   /* The length of the simple expansion.  */
2205796c8dcSSimon Schubert   int simple_len;
2215796c8dcSSimon Schubert   /* The results of a full, verbose, expansion.  This is used when
2225796c8dcSSimon Schubert      qualifying a constructor/destructor, or when in verbose mode.  */
2235796c8dcSSimon Schubert   const char *full_expansion;
2245796c8dcSSimon Schubert   /* The length of the full expansion.  */
2255796c8dcSSimon Schubert   int full_len;
2265796c8dcSSimon Schubert   /* What to set the last_name field of d_info to; NULL if we should
2275796c8dcSSimon Schubert      not set it.  This is only relevant when qualifying a
2285796c8dcSSimon Schubert      constructor/destructor.  */
2295796c8dcSSimon Schubert   const char *set_last_name;
2305796c8dcSSimon Schubert   /* The length of set_last_name.  */
2315796c8dcSSimon Schubert   int set_last_name_len;
2325796c8dcSSimon Schubert };
2335796c8dcSSimon Schubert 
2345796c8dcSSimon Schubert /* Accessors for subtrees of struct demangle_component.  */
2355796c8dcSSimon Schubert 
2365796c8dcSSimon Schubert #define d_left(dc) ((dc)->u.s_binary.left)
2375796c8dcSSimon Schubert #define d_right(dc) ((dc)->u.s_binary.right)
2385796c8dcSSimon Schubert 
2395796c8dcSSimon Schubert /* A list of templates.  This is used while printing.  */
2405796c8dcSSimon Schubert 
2415796c8dcSSimon Schubert struct d_print_template
2425796c8dcSSimon Schubert {
2435796c8dcSSimon Schubert   /* Next template on the list.  */
2445796c8dcSSimon Schubert   struct d_print_template *next;
2455796c8dcSSimon Schubert   /* This template.  */
2465796c8dcSSimon Schubert   const struct demangle_component *template_decl;
2475796c8dcSSimon Schubert };
2485796c8dcSSimon Schubert 
2495796c8dcSSimon Schubert /* A list of type modifiers.  This is used while printing.  */
2505796c8dcSSimon Schubert 
2515796c8dcSSimon Schubert struct d_print_mod
2525796c8dcSSimon Schubert {
2535796c8dcSSimon Schubert   /* Next modifier on the list.  These are in the reverse of the order
2545796c8dcSSimon Schubert      in which they appeared in the mangled string.  */
2555796c8dcSSimon Schubert   struct d_print_mod *next;
2565796c8dcSSimon Schubert   /* The modifier.  */
2575796c8dcSSimon Schubert   const struct demangle_component *mod;
2585796c8dcSSimon Schubert   /* Whether this modifier was printed.  */
2595796c8dcSSimon Schubert   int printed;
2605796c8dcSSimon Schubert   /* The list of templates which applies to this modifier.  */
2615796c8dcSSimon Schubert   struct d_print_template *templates;
2625796c8dcSSimon Schubert };
2635796c8dcSSimon Schubert 
2645796c8dcSSimon Schubert /* We use these structures to hold information during printing.  */
2655796c8dcSSimon Schubert 
2665796c8dcSSimon Schubert struct d_growable_string
2675796c8dcSSimon Schubert {
2685796c8dcSSimon Schubert   /* Buffer holding the result.  */
2695796c8dcSSimon Schubert   char *buf;
2705796c8dcSSimon Schubert   /* Current length of data in buffer.  */
2715796c8dcSSimon Schubert   size_t len;
2725796c8dcSSimon Schubert   /* Allocated size of buffer.  */
2735796c8dcSSimon Schubert   size_t alc;
2745796c8dcSSimon Schubert   /* Set to 1 if we had a memory allocation failure.  */
2755796c8dcSSimon Schubert   int allocation_failure;
2765796c8dcSSimon Schubert };
2775796c8dcSSimon Schubert 
2785796c8dcSSimon Schubert enum { D_PRINT_BUFFER_LENGTH = 256 };
2795796c8dcSSimon Schubert struct d_print_info
2805796c8dcSSimon Schubert {
2815796c8dcSSimon Schubert   /* Fixed-length allocated buffer for demangled data, flushed to the
2825796c8dcSSimon Schubert      callback with a NUL termination once full.  */
2835796c8dcSSimon Schubert   char buf[D_PRINT_BUFFER_LENGTH];
2845796c8dcSSimon Schubert   /* Current length of data in buffer.  */
2855796c8dcSSimon Schubert   size_t len;
2865796c8dcSSimon Schubert   /* The last character printed, saved individually so that it survives
2875796c8dcSSimon Schubert      any buffer flush.  */
2885796c8dcSSimon Schubert   char last_char;
2895796c8dcSSimon Schubert   /* Callback function to handle demangled buffer flush.  */
2905796c8dcSSimon Schubert   demangle_callbackref callback;
2915796c8dcSSimon Schubert   /* Opaque callback argument.  */
2925796c8dcSSimon Schubert   void *opaque;
2935796c8dcSSimon Schubert   /* The current list of templates, if any.  */
2945796c8dcSSimon Schubert   struct d_print_template *templates;
2955796c8dcSSimon Schubert   /* The current list of modifiers (e.g., pointer, reference, etc.),
2965796c8dcSSimon Schubert      if any.  */
2975796c8dcSSimon Schubert   struct d_print_mod *modifiers;
2985796c8dcSSimon Schubert   /* Set to 1 if we saw a demangling error.  */
2995796c8dcSSimon Schubert   int demangle_failure;
3005796c8dcSSimon Schubert   /* The current index into any template argument packs we are using
3015796c8dcSSimon Schubert      for printing.  */
3025796c8dcSSimon Schubert   int pack_index;
303cf7f2e2dSJohn Marino   /* Number of d_print_flush calls so far.  */
304cf7f2e2dSJohn Marino   unsigned long int flush_count;
3055796c8dcSSimon Schubert };
3065796c8dcSSimon Schubert 
3075796c8dcSSimon Schubert #ifdef CP_DEMANGLE_DEBUG
3085796c8dcSSimon Schubert static void d_dump (struct demangle_component *, int);
3095796c8dcSSimon Schubert #endif
3105796c8dcSSimon Schubert 
3115796c8dcSSimon Schubert static struct demangle_component *
3125796c8dcSSimon Schubert d_make_empty (struct d_info *);
3135796c8dcSSimon Schubert 
3145796c8dcSSimon Schubert static struct demangle_component *
3155796c8dcSSimon Schubert d_make_comp (struct d_info *, enum demangle_component_type,
3165796c8dcSSimon Schubert              struct demangle_component *,
3175796c8dcSSimon Schubert              struct demangle_component *);
3185796c8dcSSimon Schubert 
3195796c8dcSSimon Schubert static struct demangle_component *
3205796c8dcSSimon Schubert d_make_name (struct d_info *, const char *, int);
3215796c8dcSSimon Schubert 
3225796c8dcSSimon Schubert static struct demangle_component *
323c50c785cSJohn Marino d_make_demangle_mangled_name (struct d_info *, const char *);
324c50c785cSJohn Marino 
325c50c785cSJohn Marino static struct demangle_component *
3265796c8dcSSimon Schubert d_make_builtin_type (struct d_info *,
3275796c8dcSSimon Schubert                      const struct demangle_builtin_type_info *);
3285796c8dcSSimon Schubert 
3295796c8dcSSimon Schubert static struct demangle_component *
3305796c8dcSSimon Schubert d_make_operator (struct d_info *,
3315796c8dcSSimon Schubert                  const struct demangle_operator_info *);
3325796c8dcSSimon Schubert 
3335796c8dcSSimon Schubert static struct demangle_component *
3345796c8dcSSimon Schubert d_make_extended_operator (struct d_info *, int,
3355796c8dcSSimon Schubert                           struct demangle_component *);
3365796c8dcSSimon Schubert 
3375796c8dcSSimon Schubert static struct demangle_component *
3385796c8dcSSimon Schubert d_make_ctor (struct d_info *, enum gnu_v3_ctor_kinds,
3395796c8dcSSimon Schubert              struct demangle_component *);
3405796c8dcSSimon Schubert 
3415796c8dcSSimon Schubert static struct demangle_component *
3425796c8dcSSimon Schubert d_make_dtor (struct d_info *, enum gnu_v3_dtor_kinds,
3435796c8dcSSimon Schubert              struct demangle_component *);
3445796c8dcSSimon Schubert 
3455796c8dcSSimon Schubert static struct demangle_component *
3465796c8dcSSimon Schubert d_make_template_param (struct d_info *, long);
3475796c8dcSSimon Schubert 
3485796c8dcSSimon Schubert static struct demangle_component *
3495796c8dcSSimon Schubert d_make_sub (struct d_info *, const char *, int);
3505796c8dcSSimon Schubert 
3515796c8dcSSimon Schubert static int
3525796c8dcSSimon Schubert has_return_type (struct demangle_component *);
3535796c8dcSSimon Schubert 
3545796c8dcSSimon Schubert static int
3555796c8dcSSimon Schubert is_ctor_dtor_or_conversion (struct demangle_component *);
3565796c8dcSSimon Schubert 
3575796c8dcSSimon Schubert static struct demangle_component *d_encoding (struct d_info *, int);
3585796c8dcSSimon Schubert 
3595796c8dcSSimon Schubert static struct demangle_component *d_name (struct d_info *);
3605796c8dcSSimon Schubert 
3615796c8dcSSimon Schubert static struct demangle_component *d_nested_name (struct d_info *);
3625796c8dcSSimon Schubert 
3635796c8dcSSimon Schubert static struct demangle_component *d_prefix (struct d_info *);
3645796c8dcSSimon Schubert 
3655796c8dcSSimon Schubert static struct demangle_component *d_unqualified_name (struct d_info *);
3665796c8dcSSimon Schubert 
3675796c8dcSSimon Schubert static struct demangle_component *d_source_name (struct d_info *);
3685796c8dcSSimon Schubert 
3695796c8dcSSimon Schubert static long d_number (struct d_info *);
3705796c8dcSSimon Schubert 
3715796c8dcSSimon Schubert static struct demangle_component *d_identifier (struct d_info *, int);
3725796c8dcSSimon Schubert 
3735796c8dcSSimon Schubert static struct demangle_component *d_operator_name (struct d_info *);
3745796c8dcSSimon Schubert 
3755796c8dcSSimon Schubert static struct demangle_component *d_special_name (struct d_info *);
3765796c8dcSSimon Schubert 
3775796c8dcSSimon Schubert static int d_call_offset (struct d_info *, int);
3785796c8dcSSimon Schubert 
3795796c8dcSSimon Schubert static struct demangle_component *d_ctor_dtor_name (struct d_info *);
3805796c8dcSSimon Schubert 
3815796c8dcSSimon Schubert static struct demangle_component **
3825796c8dcSSimon Schubert d_cv_qualifiers (struct d_info *, struct demangle_component **, int);
3835796c8dcSSimon Schubert 
3845796c8dcSSimon Schubert static struct demangle_component *
3855796c8dcSSimon Schubert d_function_type (struct d_info *);
3865796c8dcSSimon Schubert 
3875796c8dcSSimon Schubert static struct demangle_component *
3885796c8dcSSimon Schubert d_bare_function_type (struct d_info *, int);
3895796c8dcSSimon Schubert 
3905796c8dcSSimon Schubert static struct demangle_component *
3915796c8dcSSimon Schubert d_class_enum_type (struct d_info *);
3925796c8dcSSimon Schubert 
3935796c8dcSSimon Schubert static struct demangle_component *d_array_type (struct d_info *);
3945796c8dcSSimon Schubert 
395cf7f2e2dSJohn Marino static struct demangle_component *d_vector_type (struct d_info *);
396cf7f2e2dSJohn Marino 
3975796c8dcSSimon Schubert static struct demangle_component *
3985796c8dcSSimon Schubert d_pointer_to_member_type (struct d_info *);
3995796c8dcSSimon Schubert 
4005796c8dcSSimon Schubert static struct demangle_component *
4015796c8dcSSimon Schubert d_template_param (struct d_info *);
4025796c8dcSSimon Schubert 
4035796c8dcSSimon Schubert static struct demangle_component *d_template_args (struct d_info *);
4045796c8dcSSimon Schubert 
4055796c8dcSSimon Schubert static struct demangle_component *
4065796c8dcSSimon Schubert d_template_arg (struct d_info *);
4075796c8dcSSimon Schubert 
4085796c8dcSSimon Schubert static struct demangle_component *d_expression (struct d_info *);
4095796c8dcSSimon Schubert 
4105796c8dcSSimon Schubert static struct demangle_component *d_expr_primary (struct d_info *);
4115796c8dcSSimon Schubert 
4125796c8dcSSimon Schubert static struct demangle_component *d_local_name (struct d_info *);
4135796c8dcSSimon Schubert 
4145796c8dcSSimon Schubert static int d_discriminator (struct d_info *);
4155796c8dcSSimon Schubert 
416cf7f2e2dSJohn Marino static struct demangle_component *d_lambda (struct d_info *);
417cf7f2e2dSJohn Marino 
418cf7f2e2dSJohn Marino static struct demangle_component *d_unnamed_type (struct d_info *);
419cf7f2e2dSJohn Marino 
420a45ae5f8SJohn Marino static struct demangle_component *
421a45ae5f8SJohn Marino d_clone_suffix (struct d_info *, struct demangle_component *);
422a45ae5f8SJohn Marino 
4235796c8dcSSimon Schubert static int
4245796c8dcSSimon Schubert d_add_substitution (struct d_info *, struct demangle_component *);
4255796c8dcSSimon Schubert 
4265796c8dcSSimon Schubert static struct demangle_component *d_substitution (struct d_info *, int);
4275796c8dcSSimon Schubert 
4285796c8dcSSimon Schubert static void d_growable_string_init (struct d_growable_string *, size_t);
4295796c8dcSSimon Schubert 
4305796c8dcSSimon Schubert static inline void
4315796c8dcSSimon Schubert d_growable_string_resize (struct d_growable_string *, size_t);
4325796c8dcSSimon Schubert 
4335796c8dcSSimon Schubert static inline void
4345796c8dcSSimon Schubert d_growable_string_append_buffer (struct d_growable_string *,
4355796c8dcSSimon Schubert                                  const char *, size_t);
4365796c8dcSSimon Schubert static void
4375796c8dcSSimon Schubert d_growable_string_callback_adapter (const char *, size_t, void *);
4385796c8dcSSimon Schubert 
4395796c8dcSSimon Schubert static void
440c50c785cSJohn Marino d_print_init (struct d_print_info *, demangle_callbackref, void *);
4415796c8dcSSimon Schubert 
4425796c8dcSSimon Schubert static inline void d_print_error (struct d_print_info *);
4435796c8dcSSimon Schubert 
4445796c8dcSSimon Schubert static inline int d_print_saw_error (struct d_print_info *);
4455796c8dcSSimon Schubert 
4465796c8dcSSimon Schubert static inline void d_print_flush (struct d_print_info *);
4475796c8dcSSimon Schubert 
4485796c8dcSSimon Schubert static inline void d_append_char (struct d_print_info *, char);
4495796c8dcSSimon Schubert 
4505796c8dcSSimon Schubert static inline void d_append_buffer (struct d_print_info *,
4515796c8dcSSimon Schubert                                     const char *, size_t);
4525796c8dcSSimon Schubert 
4535796c8dcSSimon Schubert static inline void d_append_string (struct d_print_info *, const char *);
4545796c8dcSSimon Schubert 
4555796c8dcSSimon Schubert static inline char d_last_char (struct d_print_info *);
4565796c8dcSSimon Schubert 
4575796c8dcSSimon Schubert static void
458c50c785cSJohn Marino d_print_comp (struct d_print_info *, int, const struct demangle_component *);
4595796c8dcSSimon Schubert 
4605796c8dcSSimon Schubert static void
4615796c8dcSSimon Schubert d_print_java_identifier (struct d_print_info *, const char *, int);
4625796c8dcSSimon Schubert 
4635796c8dcSSimon Schubert static void
464c50c785cSJohn Marino d_print_mod_list (struct d_print_info *, int, struct d_print_mod *, int);
4655796c8dcSSimon Schubert 
4665796c8dcSSimon Schubert static void
467c50c785cSJohn Marino d_print_mod (struct d_print_info *, int, const struct demangle_component *);
4685796c8dcSSimon Schubert 
4695796c8dcSSimon Schubert static void
470c50c785cSJohn Marino d_print_function_type (struct d_print_info *, int,
4715796c8dcSSimon Schubert                        const struct demangle_component *,
4725796c8dcSSimon Schubert                        struct d_print_mod *);
4735796c8dcSSimon Schubert 
4745796c8dcSSimon Schubert static void
475c50c785cSJohn Marino d_print_array_type (struct d_print_info *, int,
4765796c8dcSSimon Schubert                     const struct demangle_component *,
4775796c8dcSSimon Schubert                     struct d_print_mod *);
4785796c8dcSSimon Schubert 
4795796c8dcSSimon Schubert static void
480c50c785cSJohn Marino d_print_expr_op (struct d_print_info *, int, const struct demangle_component *);
4815796c8dcSSimon Schubert 
4825796c8dcSSimon Schubert static void
483c50c785cSJohn Marino d_print_cast (struct d_print_info *, int, const struct demangle_component *);
4845796c8dcSSimon Schubert 
4855796c8dcSSimon Schubert static int d_demangle_callback (const char *, int,
4865796c8dcSSimon Schubert                                 demangle_callbackref, void *);
4875796c8dcSSimon Schubert static char *d_demangle (const char *, int, size_t *);
4885796c8dcSSimon Schubert 
4895796c8dcSSimon Schubert #ifdef CP_DEMANGLE_DEBUG
4905796c8dcSSimon Schubert 
4915796c8dcSSimon Schubert static void
d_dump(struct demangle_component * dc,int indent)4925796c8dcSSimon Schubert d_dump (struct demangle_component *dc, int indent)
4935796c8dcSSimon Schubert {
4945796c8dcSSimon Schubert   int i;
4955796c8dcSSimon Schubert 
4965796c8dcSSimon Schubert   if (dc == NULL)
4975796c8dcSSimon Schubert     {
4985796c8dcSSimon Schubert       if (indent == 0)
4995796c8dcSSimon Schubert         printf ("failed demangling\n");
5005796c8dcSSimon Schubert       return;
5015796c8dcSSimon Schubert     }
5025796c8dcSSimon Schubert 
5035796c8dcSSimon Schubert   for (i = 0; i < indent; ++i)
5045796c8dcSSimon Schubert     putchar (' ');
5055796c8dcSSimon Schubert 
5065796c8dcSSimon Schubert   switch (dc->type)
5075796c8dcSSimon Schubert     {
5085796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_NAME:
5095796c8dcSSimon Schubert       printf ("name '%.*s'\n", dc->u.s_name.len, dc->u.s_name.s);
5105796c8dcSSimon Schubert       return;
511*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TAGGED_NAME:
512*ef5ccd6cSJohn Marino       printf ("tagged name\n");
513*ef5ccd6cSJohn Marino       d_dump (dc->u.s_binary.left, indent + 2);
514*ef5ccd6cSJohn Marino       d_dump (dc->u.s_binary.right, indent + 2);
515*ef5ccd6cSJohn Marino       return;
5165796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
5175796c8dcSSimon Schubert       printf ("template parameter %ld\n", dc->u.s_number.number);
5185796c8dcSSimon Schubert       return;
5195796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CTOR:
5205796c8dcSSimon Schubert       printf ("constructor %d\n", (int) dc->u.s_ctor.kind);
5215796c8dcSSimon Schubert       d_dump (dc->u.s_ctor.name, indent + 2);
5225796c8dcSSimon Schubert       return;
5235796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_DTOR:
5245796c8dcSSimon Schubert       printf ("destructor %d\n", (int) dc->u.s_dtor.kind);
5255796c8dcSSimon Schubert       d_dump (dc->u.s_dtor.name, indent + 2);
5265796c8dcSSimon Schubert       return;
5275796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_SUB_STD:
5285796c8dcSSimon Schubert       printf ("standard substitution %s\n", dc->u.s_string.string);
5295796c8dcSSimon Schubert       return;
5305796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_BUILTIN_TYPE:
5315796c8dcSSimon Schubert       printf ("builtin type %s\n", dc->u.s_builtin.type->name);
5325796c8dcSSimon Schubert       return;
5335796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_OPERATOR:
5345796c8dcSSimon Schubert       printf ("operator %s\n", dc->u.s_operator.op->name);
5355796c8dcSSimon Schubert       return;
5365796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
5375796c8dcSSimon Schubert       printf ("extended operator with %d args\n",
5385796c8dcSSimon Schubert 	      dc->u.s_extended_operator.args);
5395796c8dcSSimon Schubert       d_dump (dc->u.s_extended_operator.name, indent + 2);
5405796c8dcSSimon Schubert       return;
5415796c8dcSSimon Schubert 
5425796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_QUAL_NAME:
5435796c8dcSSimon Schubert       printf ("qualified name\n");
5445796c8dcSSimon Schubert       break;
5455796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LOCAL_NAME:
5465796c8dcSSimon Schubert       printf ("local name\n");
5475796c8dcSSimon Schubert       break;
5485796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPED_NAME:
5495796c8dcSSimon Schubert       printf ("typed name\n");
5505796c8dcSSimon Schubert       break;
5515796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE:
5525796c8dcSSimon Schubert       printf ("template\n");
5535796c8dcSSimon Schubert       break;
5545796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VTABLE:
5555796c8dcSSimon Schubert       printf ("vtable\n");
5565796c8dcSSimon Schubert       break;
5575796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VTT:
5585796c8dcSSimon Schubert       printf ("VTT\n");
5595796c8dcSSimon Schubert       break;
5605796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
5615796c8dcSSimon Schubert       printf ("construction vtable\n");
5625796c8dcSSimon Schubert       break;
5635796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPEINFO:
5645796c8dcSSimon Schubert       printf ("typeinfo\n");
5655796c8dcSSimon Schubert       break;
5665796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPEINFO_NAME:
5675796c8dcSSimon Schubert       printf ("typeinfo name\n");
5685796c8dcSSimon Schubert       break;
5695796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPEINFO_FN:
5705796c8dcSSimon Schubert       printf ("typeinfo function\n");
5715796c8dcSSimon Schubert       break;
5725796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_THUNK:
5735796c8dcSSimon Schubert       printf ("thunk\n");
5745796c8dcSSimon Schubert       break;
5755796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
5765796c8dcSSimon Schubert       printf ("virtual thunk\n");
5775796c8dcSSimon Schubert       break;
5785796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COVARIANT_THUNK:
5795796c8dcSSimon Schubert       printf ("covariant thunk\n");
5805796c8dcSSimon Schubert       break;
5815796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_JAVA_CLASS:
5825796c8dcSSimon Schubert       printf ("java class\n");
5835796c8dcSSimon Schubert       break;
5845796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_GUARD:
5855796c8dcSSimon Schubert       printf ("guard\n");
5865796c8dcSSimon Schubert       break;
5875796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_REFTEMP:
5885796c8dcSSimon Schubert       printf ("reference temporary\n");
5895796c8dcSSimon Schubert       break;
5905796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
5915796c8dcSSimon Schubert       printf ("hidden alias\n");
5925796c8dcSSimon Schubert       break;
593a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
594a45ae5f8SJohn Marino       printf ("transaction clone\n");
595a45ae5f8SJohn Marino       break;
596a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
597a45ae5f8SJohn Marino       printf ("non-transaction clone\n");
598a45ae5f8SJohn Marino       break;
5995796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RESTRICT:
6005796c8dcSSimon Schubert       printf ("restrict\n");
6015796c8dcSSimon Schubert       break;
6025796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VOLATILE:
6035796c8dcSSimon Schubert       printf ("volatile\n");
6045796c8dcSSimon Schubert       break;
6055796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONST:
6065796c8dcSSimon Schubert       printf ("const\n");
6075796c8dcSSimon Schubert       break;
6085796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RESTRICT_THIS:
6095796c8dcSSimon Schubert       printf ("restrict this\n");
6105796c8dcSSimon Schubert       break;
6115796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VOLATILE_THIS:
6125796c8dcSSimon Schubert       printf ("volatile this\n");
6135796c8dcSSimon Schubert       break;
6145796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONST_THIS:
6155796c8dcSSimon Schubert       printf ("const this\n");
6165796c8dcSSimon Schubert       break;
6175796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
6185796c8dcSSimon Schubert       printf ("vendor type qualifier\n");
6195796c8dcSSimon Schubert       break;
6205796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_POINTER:
6215796c8dcSSimon Schubert       printf ("pointer\n");
6225796c8dcSSimon Schubert       break;
6235796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_REFERENCE:
6245796c8dcSSimon Schubert       printf ("reference\n");
6255796c8dcSSimon Schubert       break;
6265796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
6275796c8dcSSimon Schubert       printf ("rvalue reference\n");
6285796c8dcSSimon Schubert       break;
6295796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COMPLEX:
6305796c8dcSSimon Schubert       printf ("complex\n");
6315796c8dcSSimon Schubert       break;
6325796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_IMAGINARY:
6335796c8dcSSimon Schubert       printf ("imaginary\n");
6345796c8dcSSimon Schubert       break;
6355796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VENDOR_TYPE:
6365796c8dcSSimon Schubert       printf ("vendor type\n");
6375796c8dcSSimon Schubert       break;
6385796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_FUNCTION_TYPE:
6395796c8dcSSimon Schubert       printf ("function type\n");
6405796c8dcSSimon Schubert       break;
6415796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_ARRAY_TYPE:
6425796c8dcSSimon Schubert       printf ("array type\n");
6435796c8dcSSimon Schubert       break;
6445796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_PTRMEM_TYPE:
6455796c8dcSSimon Schubert       printf ("pointer to member type\n");
6465796c8dcSSimon Schubert       break;
6475796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_FIXED_TYPE:
6485796c8dcSSimon Schubert       printf ("fixed-point type\n");
6495796c8dcSSimon Schubert       break;
6505796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_ARGLIST:
6515796c8dcSSimon Schubert       printf ("argument list\n");
6525796c8dcSSimon Schubert       break;
6535796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
6545796c8dcSSimon Schubert       printf ("template argument list\n");
6555796c8dcSSimon Schubert       break;
656*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_INITIALIZER_LIST:
657*ef5ccd6cSJohn Marino       printf ("initializer list\n");
658*ef5ccd6cSJohn Marino       break;
6595796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CAST:
6605796c8dcSSimon Schubert       printf ("cast\n");
6615796c8dcSSimon Schubert       break;
662*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_NULLARY:
663*ef5ccd6cSJohn Marino       printf ("nullary operator\n");
664*ef5ccd6cSJohn Marino       break;
6655796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_UNARY:
6665796c8dcSSimon Schubert       printf ("unary operator\n");
6675796c8dcSSimon Schubert       break;
6685796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_BINARY:
6695796c8dcSSimon Schubert       printf ("binary operator\n");
6705796c8dcSSimon Schubert       break;
6715796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_BINARY_ARGS:
6725796c8dcSSimon Schubert       printf ("binary operator arguments\n");
6735796c8dcSSimon Schubert       break;
6745796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TRINARY:
6755796c8dcSSimon Schubert       printf ("trinary operator\n");
6765796c8dcSSimon Schubert       break;
6775796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TRINARY_ARG1:
6785796c8dcSSimon Schubert       printf ("trinary operator arguments 1\n");
6795796c8dcSSimon Schubert       break;
6805796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TRINARY_ARG2:
6815796c8dcSSimon Schubert       printf ("trinary operator arguments 1\n");
6825796c8dcSSimon Schubert       break;
6835796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LITERAL:
6845796c8dcSSimon Schubert       printf ("literal\n");
6855796c8dcSSimon Schubert       break;
6865796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LITERAL_NEG:
6875796c8dcSSimon Schubert       printf ("negative literal\n");
6885796c8dcSSimon Schubert       break;
6895796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_JAVA_RESOURCE:
6905796c8dcSSimon Schubert       printf ("java resource\n");
6915796c8dcSSimon Schubert       break;
6925796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COMPOUND_NAME:
6935796c8dcSSimon Schubert       printf ("compound name\n");
6945796c8dcSSimon Schubert       break;
6955796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CHARACTER:
6965796c8dcSSimon Schubert       printf ("character '%c'\n",  dc->u.s_character.character);
6975796c8dcSSimon Schubert       return;
6985796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_DECLTYPE:
6995796c8dcSSimon Schubert       printf ("decltype\n");
7005796c8dcSSimon Schubert       break;
7015796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_PACK_EXPANSION:
7025796c8dcSSimon Schubert       printf ("pack expansion\n");
7035796c8dcSSimon Schubert       break;
704*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TLS_INIT:
705*ef5ccd6cSJohn Marino       printf ("tls init function\n");
706*ef5ccd6cSJohn Marino       break;
707*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TLS_WRAPPER:
708*ef5ccd6cSJohn Marino       printf ("tls wrapper function\n");
709*ef5ccd6cSJohn Marino       break;
710*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_DEFAULT_ARG:
711*ef5ccd6cSJohn Marino       printf ("default argument %d\n", dc->u.s_unary_num.num);
712*ef5ccd6cSJohn Marino       d_dump (dc->u.s_unary_num.sub, indent+2);
713*ef5ccd6cSJohn Marino       return;
714*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_LAMBDA:
715*ef5ccd6cSJohn Marino       printf ("lambda %d\n", dc->u.s_unary_num.num);
716*ef5ccd6cSJohn Marino       d_dump (dc->u.s_unary_num.sub, indent+2);
717*ef5ccd6cSJohn Marino       return;
7185796c8dcSSimon Schubert     }
7195796c8dcSSimon Schubert 
7205796c8dcSSimon Schubert   d_dump (d_left (dc), indent + 2);
7215796c8dcSSimon Schubert   d_dump (d_right (dc), indent + 2);
7225796c8dcSSimon Schubert }
7235796c8dcSSimon Schubert 
7245796c8dcSSimon Schubert #endif /* CP_DEMANGLE_DEBUG */
7255796c8dcSSimon Schubert 
7265796c8dcSSimon Schubert /* Fill in a DEMANGLE_COMPONENT_NAME.  */
7275796c8dcSSimon Schubert 
7285796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
7295796c8dcSSimon Schubert int
cplus_demangle_fill_name(struct demangle_component * p,const char * s,int len)7305796c8dcSSimon Schubert cplus_demangle_fill_name (struct demangle_component *p, const char *s, int len)
7315796c8dcSSimon Schubert {
7325796c8dcSSimon Schubert   if (p == NULL || s == NULL || len == 0)
7335796c8dcSSimon Schubert     return 0;
7345796c8dcSSimon Schubert   p->type = DEMANGLE_COMPONENT_NAME;
7355796c8dcSSimon Schubert   p->u.s_name.s = s;
7365796c8dcSSimon Schubert   p->u.s_name.len = len;
7375796c8dcSSimon Schubert   return 1;
7385796c8dcSSimon Schubert }
7395796c8dcSSimon Schubert 
7405796c8dcSSimon Schubert /* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR.  */
7415796c8dcSSimon Schubert 
7425796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
7435796c8dcSSimon Schubert int
cplus_demangle_fill_extended_operator(struct demangle_component * p,int args,struct demangle_component * name)7445796c8dcSSimon Schubert cplus_demangle_fill_extended_operator (struct demangle_component *p, int args,
7455796c8dcSSimon Schubert                                        struct demangle_component *name)
7465796c8dcSSimon Schubert {
7475796c8dcSSimon Schubert   if (p == NULL || args < 0 || name == NULL)
7485796c8dcSSimon Schubert     return 0;
7495796c8dcSSimon Schubert   p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
7505796c8dcSSimon Schubert   p->u.s_extended_operator.args = args;
7515796c8dcSSimon Schubert   p->u.s_extended_operator.name = name;
7525796c8dcSSimon Schubert   return 1;
7535796c8dcSSimon Schubert }
7545796c8dcSSimon Schubert 
7555796c8dcSSimon Schubert /* Fill in a DEMANGLE_COMPONENT_CTOR.  */
7565796c8dcSSimon Schubert 
7575796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
7585796c8dcSSimon Schubert int
cplus_demangle_fill_ctor(struct demangle_component * p,enum gnu_v3_ctor_kinds kind,struct demangle_component * name)7595796c8dcSSimon Schubert cplus_demangle_fill_ctor (struct demangle_component *p,
7605796c8dcSSimon Schubert                           enum gnu_v3_ctor_kinds kind,
7615796c8dcSSimon Schubert                           struct demangle_component *name)
7625796c8dcSSimon Schubert {
7635796c8dcSSimon Schubert   if (p == NULL
7645796c8dcSSimon Schubert       || name == NULL
7655796c8dcSSimon Schubert       || (int) kind < gnu_v3_complete_object_ctor
766a45ae5f8SJohn Marino       || (int) kind > gnu_v3_object_ctor_group)
7675796c8dcSSimon Schubert     return 0;
7685796c8dcSSimon Schubert   p->type = DEMANGLE_COMPONENT_CTOR;
7695796c8dcSSimon Schubert   p->u.s_ctor.kind = kind;
7705796c8dcSSimon Schubert   p->u.s_ctor.name = name;
7715796c8dcSSimon Schubert   return 1;
7725796c8dcSSimon Schubert }
7735796c8dcSSimon Schubert 
7745796c8dcSSimon Schubert /* Fill in a DEMANGLE_COMPONENT_DTOR.  */
7755796c8dcSSimon Schubert 
7765796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
7775796c8dcSSimon Schubert int
cplus_demangle_fill_dtor(struct demangle_component * p,enum gnu_v3_dtor_kinds kind,struct demangle_component * name)7785796c8dcSSimon Schubert cplus_demangle_fill_dtor (struct demangle_component *p,
7795796c8dcSSimon Schubert                           enum gnu_v3_dtor_kinds kind,
7805796c8dcSSimon Schubert                           struct demangle_component *name)
7815796c8dcSSimon Schubert {
7825796c8dcSSimon Schubert   if (p == NULL
7835796c8dcSSimon Schubert       || name == NULL
7845796c8dcSSimon Schubert       || (int) kind < gnu_v3_deleting_dtor
785a45ae5f8SJohn Marino       || (int) kind > gnu_v3_object_dtor_group)
7865796c8dcSSimon Schubert     return 0;
7875796c8dcSSimon Schubert   p->type = DEMANGLE_COMPONENT_DTOR;
7885796c8dcSSimon Schubert   p->u.s_dtor.kind = kind;
7895796c8dcSSimon Schubert   p->u.s_dtor.name = name;
7905796c8dcSSimon Schubert   return 1;
7915796c8dcSSimon Schubert }
7925796c8dcSSimon Schubert 
7935796c8dcSSimon Schubert /* Add a new component.  */
7945796c8dcSSimon Schubert 
7955796c8dcSSimon Schubert static struct demangle_component *
d_make_empty(struct d_info * di)7965796c8dcSSimon Schubert d_make_empty (struct d_info *di)
7975796c8dcSSimon Schubert {
7985796c8dcSSimon Schubert   struct demangle_component *p;
7995796c8dcSSimon Schubert 
8005796c8dcSSimon Schubert   if (di->next_comp >= di->num_comps)
8015796c8dcSSimon Schubert     return NULL;
8025796c8dcSSimon Schubert   p = &di->comps[di->next_comp];
8035796c8dcSSimon Schubert   ++di->next_comp;
8045796c8dcSSimon Schubert   return p;
8055796c8dcSSimon Schubert }
8065796c8dcSSimon Schubert 
8075796c8dcSSimon Schubert /* Add a new generic component.  */
8085796c8dcSSimon Schubert 
8095796c8dcSSimon Schubert static struct demangle_component *
d_make_comp(struct d_info * di,enum demangle_component_type type,struct demangle_component * left,struct demangle_component * right)8105796c8dcSSimon Schubert d_make_comp (struct d_info *di, enum demangle_component_type type,
8115796c8dcSSimon Schubert              struct demangle_component *left,
8125796c8dcSSimon Schubert              struct demangle_component *right)
8135796c8dcSSimon Schubert {
8145796c8dcSSimon Schubert   struct demangle_component *p;
8155796c8dcSSimon Schubert 
8165796c8dcSSimon Schubert   /* We check for errors here.  A typical error would be a NULL return
8175796c8dcSSimon Schubert      from a subroutine.  We catch those here, and return NULL
8185796c8dcSSimon Schubert      upward.  */
8195796c8dcSSimon Schubert   switch (type)
8205796c8dcSSimon Schubert     {
8215796c8dcSSimon Schubert       /* These types require two parameters.  */
8225796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_QUAL_NAME:
8235796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LOCAL_NAME:
8245796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPED_NAME:
825*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TAGGED_NAME:
8265796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE:
8275796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
8285796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
8295796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_PTRMEM_TYPE:
8305796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_UNARY:
8315796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_BINARY:
8325796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_BINARY_ARGS:
8335796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TRINARY:
8345796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TRINARY_ARG1:
8355796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LITERAL:
8365796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LITERAL_NEG:
8375796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COMPOUND_NAME:
838cf7f2e2dSJohn Marino     case DEMANGLE_COMPONENT_VECTOR_TYPE:
839a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_CLONE:
8405796c8dcSSimon Schubert       if (left == NULL || right == NULL)
8415796c8dcSSimon Schubert 	return NULL;
8425796c8dcSSimon Schubert       break;
8435796c8dcSSimon Schubert 
8445796c8dcSSimon Schubert       /* These types only require one parameter.  */
8455796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VTABLE:
8465796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VTT:
8475796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPEINFO:
8485796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPEINFO_NAME:
8495796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPEINFO_FN:
8505796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_THUNK:
8515796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
8525796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COVARIANT_THUNK:
8535796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_JAVA_CLASS:
8545796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_GUARD:
855*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TLS_INIT:
856*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TLS_WRAPPER:
8575796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_REFTEMP:
8585796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
859a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
860a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
8615796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_POINTER:
8625796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_REFERENCE:
8635796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
8645796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COMPLEX:
8655796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_IMAGINARY:
8665796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VENDOR_TYPE:
8675796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CAST:
8685796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_JAVA_RESOURCE:
8695796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_DECLTYPE:
8705796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_PACK_EXPANSION:
8715796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
8725796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
873*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_NULLARY:
874*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TRINARY_ARG2:
8755796c8dcSSimon Schubert       if (left == NULL)
8765796c8dcSSimon Schubert 	return NULL;
8775796c8dcSSimon Schubert       break;
8785796c8dcSSimon Schubert 
8795796c8dcSSimon Schubert       /* This needs a right parameter, but the left parameter can be
8805796c8dcSSimon Schubert 	 empty.  */
8815796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_ARRAY_TYPE:
882*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_INITIALIZER_LIST:
8835796c8dcSSimon Schubert       if (right == NULL)
8845796c8dcSSimon Schubert 	return NULL;
8855796c8dcSSimon Schubert       break;
8865796c8dcSSimon Schubert 
8875796c8dcSSimon Schubert       /* These are allowed to have no parameters--in some cases they
8885796c8dcSSimon Schubert 	 will be filled in later.  */
8895796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_FUNCTION_TYPE:
8905796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RESTRICT:
8915796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VOLATILE:
8925796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONST:
8935796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RESTRICT_THIS:
8945796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VOLATILE_THIS:
8955796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONST_THIS:
8965796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_ARGLIST:
8975796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
8985796c8dcSSimon Schubert       break;
8995796c8dcSSimon Schubert 
9005796c8dcSSimon Schubert       /* Other types should not be seen here.  */
9015796c8dcSSimon Schubert     default:
9025796c8dcSSimon Schubert       return NULL;
9035796c8dcSSimon Schubert     }
9045796c8dcSSimon Schubert 
9055796c8dcSSimon Schubert   p = d_make_empty (di);
9065796c8dcSSimon Schubert   if (p != NULL)
9075796c8dcSSimon Schubert     {
9085796c8dcSSimon Schubert       p->type = type;
9095796c8dcSSimon Schubert       p->u.s_binary.left = left;
9105796c8dcSSimon Schubert       p->u.s_binary.right = right;
9115796c8dcSSimon Schubert     }
9125796c8dcSSimon Schubert   return p;
9135796c8dcSSimon Schubert }
9145796c8dcSSimon Schubert 
915c50c785cSJohn Marino /* Add a new demangle mangled name component.  */
916c50c785cSJohn Marino 
917c50c785cSJohn Marino static struct demangle_component *
d_make_demangle_mangled_name(struct d_info * di,const char * s)918c50c785cSJohn Marino d_make_demangle_mangled_name (struct d_info *di, const char *s)
919c50c785cSJohn Marino {
920c50c785cSJohn Marino   if (d_peek_char (di) != '_' || d_peek_next_char (di) != 'Z')
921c50c785cSJohn Marino     return d_make_name (di, s, strlen (s));
922c50c785cSJohn Marino   d_advance (di, 2);
923c50c785cSJohn Marino   return d_encoding (di, 0);
924c50c785cSJohn Marino }
925c50c785cSJohn Marino 
9265796c8dcSSimon Schubert /* Add a new name component.  */
9275796c8dcSSimon Schubert 
9285796c8dcSSimon Schubert static struct demangle_component *
d_make_name(struct d_info * di,const char * s,int len)9295796c8dcSSimon Schubert d_make_name (struct d_info *di, const char *s, int len)
9305796c8dcSSimon Schubert {
9315796c8dcSSimon Schubert   struct demangle_component *p;
9325796c8dcSSimon Schubert 
9335796c8dcSSimon Schubert   p = d_make_empty (di);
9345796c8dcSSimon Schubert   if (! cplus_demangle_fill_name (p, s, len))
9355796c8dcSSimon Schubert     return NULL;
9365796c8dcSSimon Schubert   return p;
9375796c8dcSSimon Schubert }
9385796c8dcSSimon Schubert 
9395796c8dcSSimon Schubert /* Add a new builtin type component.  */
9405796c8dcSSimon Schubert 
9415796c8dcSSimon Schubert static struct demangle_component *
d_make_builtin_type(struct d_info * di,const struct demangle_builtin_type_info * type)9425796c8dcSSimon Schubert d_make_builtin_type (struct d_info *di,
9435796c8dcSSimon Schubert                      const struct demangle_builtin_type_info *type)
9445796c8dcSSimon Schubert {
9455796c8dcSSimon Schubert   struct demangle_component *p;
9465796c8dcSSimon Schubert 
9475796c8dcSSimon Schubert   if (type == NULL)
9485796c8dcSSimon Schubert     return NULL;
9495796c8dcSSimon Schubert   p = d_make_empty (di);
9505796c8dcSSimon Schubert   if (p != NULL)
9515796c8dcSSimon Schubert     {
9525796c8dcSSimon Schubert       p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE;
9535796c8dcSSimon Schubert       p->u.s_builtin.type = type;
9545796c8dcSSimon Schubert     }
9555796c8dcSSimon Schubert   return p;
9565796c8dcSSimon Schubert }
9575796c8dcSSimon Schubert 
9585796c8dcSSimon Schubert /* Add a new operator component.  */
9595796c8dcSSimon Schubert 
9605796c8dcSSimon Schubert static struct demangle_component *
d_make_operator(struct d_info * di,const struct demangle_operator_info * op)9615796c8dcSSimon Schubert d_make_operator (struct d_info *di, const struct demangle_operator_info *op)
9625796c8dcSSimon Schubert {
9635796c8dcSSimon Schubert   struct demangle_component *p;
9645796c8dcSSimon Schubert 
9655796c8dcSSimon Schubert   p = d_make_empty (di);
9665796c8dcSSimon Schubert   if (p != NULL)
9675796c8dcSSimon Schubert     {
9685796c8dcSSimon Schubert       p->type = DEMANGLE_COMPONENT_OPERATOR;
9695796c8dcSSimon Schubert       p->u.s_operator.op = op;
9705796c8dcSSimon Schubert     }
9715796c8dcSSimon Schubert   return p;
9725796c8dcSSimon Schubert }
9735796c8dcSSimon Schubert 
9745796c8dcSSimon Schubert /* Add a new extended operator component.  */
9755796c8dcSSimon Schubert 
9765796c8dcSSimon Schubert static struct demangle_component *
d_make_extended_operator(struct d_info * di,int args,struct demangle_component * name)9775796c8dcSSimon Schubert d_make_extended_operator (struct d_info *di, int args,
9785796c8dcSSimon Schubert                           struct demangle_component *name)
9795796c8dcSSimon Schubert {
9805796c8dcSSimon Schubert   struct demangle_component *p;
9815796c8dcSSimon Schubert 
9825796c8dcSSimon Schubert   p = d_make_empty (di);
9835796c8dcSSimon Schubert   if (! cplus_demangle_fill_extended_operator (p, args, name))
9845796c8dcSSimon Schubert     return NULL;
9855796c8dcSSimon Schubert   return p;
9865796c8dcSSimon Schubert }
9875796c8dcSSimon Schubert 
988cf7f2e2dSJohn Marino static struct demangle_component *
d_make_default_arg(struct d_info * di,int num,struct demangle_component * sub)989cf7f2e2dSJohn Marino d_make_default_arg (struct d_info *di, int num,
990cf7f2e2dSJohn Marino 		    struct demangle_component *sub)
991cf7f2e2dSJohn Marino {
992cf7f2e2dSJohn Marino   struct demangle_component *p = d_make_empty (di);
993cf7f2e2dSJohn Marino   if (p)
994cf7f2e2dSJohn Marino     {
995cf7f2e2dSJohn Marino       p->type = DEMANGLE_COMPONENT_DEFAULT_ARG;
996cf7f2e2dSJohn Marino       p->u.s_unary_num.num = num;
997cf7f2e2dSJohn Marino       p->u.s_unary_num.sub = sub;
998cf7f2e2dSJohn Marino     }
999cf7f2e2dSJohn Marino   return p;
1000cf7f2e2dSJohn Marino }
1001cf7f2e2dSJohn Marino 
10025796c8dcSSimon Schubert /* Add a new constructor component.  */
10035796c8dcSSimon Schubert 
10045796c8dcSSimon Schubert static struct demangle_component *
d_make_ctor(struct d_info * di,enum gnu_v3_ctor_kinds kind,struct demangle_component * name)10055796c8dcSSimon Schubert d_make_ctor (struct d_info *di, enum gnu_v3_ctor_kinds kind,
10065796c8dcSSimon Schubert              struct demangle_component *name)
10075796c8dcSSimon Schubert {
10085796c8dcSSimon Schubert   struct demangle_component *p;
10095796c8dcSSimon Schubert 
10105796c8dcSSimon Schubert   p = d_make_empty (di);
10115796c8dcSSimon Schubert   if (! cplus_demangle_fill_ctor (p, kind, name))
10125796c8dcSSimon Schubert     return NULL;
10135796c8dcSSimon Schubert   return p;
10145796c8dcSSimon Schubert }
10155796c8dcSSimon Schubert 
10165796c8dcSSimon Schubert /* Add a new destructor component.  */
10175796c8dcSSimon Schubert 
10185796c8dcSSimon Schubert static struct demangle_component *
d_make_dtor(struct d_info * di,enum gnu_v3_dtor_kinds kind,struct demangle_component * name)10195796c8dcSSimon Schubert d_make_dtor (struct d_info *di, enum gnu_v3_dtor_kinds kind,
10205796c8dcSSimon Schubert              struct demangle_component *name)
10215796c8dcSSimon Schubert {
10225796c8dcSSimon Schubert   struct demangle_component *p;
10235796c8dcSSimon Schubert 
10245796c8dcSSimon Schubert   p = d_make_empty (di);
10255796c8dcSSimon Schubert   if (! cplus_demangle_fill_dtor (p, kind, name))
10265796c8dcSSimon Schubert     return NULL;
10275796c8dcSSimon Schubert   return p;
10285796c8dcSSimon Schubert }
10295796c8dcSSimon Schubert 
10305796c8dcSSimon Schubert /* Add a new template parameter.  */
10315796c8dcSSimon Schubert 
10325796c8dcSSimon Schubert static struct demangle_component *
d_make_template_param(struct d_info * di,long i)10335796c8dcSSimon Schubert d_make_template_param (struct d_info *di, long i)
10345796c8dcSSimon Schubert {
10355796c8dcSSimon Schubert   struct demangle_component *p;
10365796c8dcSSimon Schubert 
10375796c8dcSSimon Schubert   p = d_make_empty (di);
10385796c8dcSSimon Schubert   if (p != NULL)
10395796c8dcSSimon Schubert     {
10405796c8dcSSimon Schubert       p->type = DEMANGLE_COMPONENT_TEMPLATE_PARAM;
10415796c8dcSSimon Schubert       p->u.s_number.number = i;
10425796c8dcSSimon Schubert     }
10435796c8dcSSimon Schubert   return p;
10445796c8dcSSimon Schubert }
10455796c8dcSSimon Schubert 
10465796c8dcSSimon Schubert /* Add a new function parameter.  */
10475796c8dcSSimon Schubert 
10485796c8dcSSimon Schubert static struct demangle_component *
d_make_function_param(struct d_info * di,long i)10495796c8dcSSimon Schubert d_make_function_param (struct d_info *di, long i)
10505796c8dcSSimon Schubert {
10515796c8dcSSimon Schubert   struct demangle_component *p;
10525796c8dcSSimon Schubert 
10535796c8dcSSimon Schubert   p = d_make_empty (di);
10545796c8dcSSimon Schubert   if (p != NULL)
10555796c8dcSSimon Schubert     {
10565796c8dcSSimon Schubert       p->type = DEMANGLE_COMPONENT_FUNCTION_PARAM;
10575796c8dcSSimon Schubert       p->u.s_number.number = i;
10585796c8dcSSimon Schubert     }
10595796c8dcSSimon Schubert   return p;
10605796c8dcSSimon Schubert }
10615796c8dcSSimon Schubert 
10625796c8dcSSimon Schubert /* Add a new standard substitution component.  */
10635796c8dcSSimon Schubert 
10645796c8dcSSimon Schubert static struct demangle_component *
d_make_sub(struct d_info * di,const char * name,int len)10655796c8dcSSimon Schubert d_make_sub (struct d_info *di, const char *name, int len)
10665796c8dcSSimon Schubert {
10675796c8dcSSimon Schubert   struct demangle_component *p;
10685796c8dcSSimon Schubert 
10695796c8dcSSimon Schubert   p = d_make_empty (di);
10705796c8dcSSimon Schubert   if (p != NULL)
10715796c8dcSSimon Schubert     {
10725796c8dcSSimon Schubert       p->type = DEMANGLE_COMPONENT_SUB_STD;
10735796c8dcSSimon Schubert       p->u.s_string.string = name;
10745796c8dcSSimon Schubert       p->u.s_string.len = len;
10755796c8dcSSimon Schubert     }
10765796c8dcSSimon Schubert   return p;
10775796c8dcSSimon Schubert }
10785796c8dcSSimon Schubert 
1079a45ae5f8SJohn Marino /* <mangled-name> ::= _Z <encoding> [<clone-suffix>]*
10805796c8dcSSimon Schubert 
10815796c8dcSSimon Schubert    TOP_LEVEL is non-zero when called at the top level.  */
10825796c8dcSSimon Schubert 
10835796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
10845796c8dcSSimon Schubert struct demangle_component *
cplus_demangle_mangled_name(struct d_info * di,int top_level)10855796c8dcSSimon Schubert cplus_demangle_mangled_name (struct d_info *di, int top_level)
10865796c8dcSSimon Schubert {
1087a45ae5f8SJohn Marino   struct demangle_component *p;
1088a45ae5f8SJohn Marino 
10895796c8dcSSimon Schubert   if (! d_check_char (di, '_')
10905796c8dcSSimon Schubert       /* Allow missing _ if not at toplevel to work around a
10915796c8dcSSimon Schubert 	 bug in G++ abi-version=2 mangling; see the comment in
10925796c8dcSSimon Schubert 	 write_template_arg.  */
10935796c8dcSSimon Schubert       && top_level)
10945796c8dcSSimon Schubert     return NULL;
10955796c8dcSSimon Schubert   if (! d_check_char (di, 'Z'))
10965796c8dcSSimon Schubert     return NULL;
1097a45ae5f8SJohn Marino   p = d_encoding (di, top_level);
1098a45ae5f8SJohn Marino 
1099a45ae5f8SJohn Marino   /* If at top level and parsing parameters, check for a clone
1100a45ae5f8SJohn Marino      suffix.  */
1101a45ae5f8SJohn Marino   if (top_level && (di->options & DMGL_PARAMS) != 0)
1102a45ae5f8SJohn Marino     while (d_peek_char (di) == '.'
1103a45ae5f8SJohn Marino 	   && (IS_LOWER (d_peek_next_char (di))
1104a45ae5f8SJohn Marino 	       || d_peek_next_char (di) == '_'
1105a45ae5f8SJohn Marino 	       || IS_DIGIT (d_peek_next_char (di))))
1106a45ae5f8SJohn Marino       p = d_clone_suffix (di, p);
1107a45ae5f8SJohn Marino 
1108a45ae5f8SJohn Marino   return p;
11095796c8dcSSimon Schubert }
11105796c8dcSSimon Schubert 
11115796c8dcSSimon Schubert /* Return whether a function should have a return type.  The argument
11125796c8dcSSimon Schubert    is the function name, which may be qualified in various ways.  The
11135796c8dcSSimon Schubert    rules are that template functions have return types with some
11145796c8dcSSimon Schubert    exceptions, function types which are not part of a function name
11155796c8dcSSimon Schubert    mangling have return types with some exceptions, and non-template
11165796c8dcSSimon Schubert    function names do not have return types.  The exceptions are that
11175796c8dcSSimon Schubert    constructors, destructors, and conversion operators do not have
11185796c8dcSSimon Schubert    return types.  */
11195796c8dcSSimon Schubert 
11205796c8dcSSimon Schubert static int
has_return_type(struct demangle_component * dc)11215796c8dcSSimon Schubert has_return_type (struct demangle_component *dc)
11225796c8dcSSimon Schubert {
11235796c8dcSSimon Schubert   if (dc == NULL)
11245796c8dcSSimon Schubert     return 0;
11255796c8dcSSimon Schubert   switch (dc->type)
11265796c8dcSSimon Schubert     {
11275796c8dcSSimon Schubert     default:
11285796c8dcSSimon Schubert       return 0;
11295796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE:
11305796c8dcSSimon Schubert       return ! is_ctor_dtor_or_conversion (d_left (dc));
11315796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RESTRICT_THIS:
11325796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VOLATILE_THIS:
11335796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONST_THIS:
11345796c8dcSSimon Schubert       return has_return_type (d_left (dc));
11355796c8dcSSimon Schubert     }
11365796c8dcSSimon Schubert }
11375796c8dcSSimon Schubert 
11385796c8dcSSimon Schubert /* Return whether a name is a constructor, a destructor, or a
11395796c8dcSSimon Schubert    conversion operator.  */
11405796c8dcSSimon Schubert 
11415796c8dcSSimon Schubert static int
is_ctor_dtor_or_conversion(struct demangle_component * dc)11425796c8dcSSimon Schubert is_ctor_dtor_or_conversion (struct demangle_component *dc)
11435796c8dcSSimon Schubert {
11445796c8dcSSimon Schubert   if (dc == NULL)
11455796c8dcSSimon Schubert     return 0;
11465796c8dcSSimon Schubert   switch (dc->type)
11475796c8dcSSimon Schubert     {
11485796c8dcSSimon Schubert     default:
11495796c8dcSSimon Schubert       return 0;
11505796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_QUAL_NAME:
11515796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LOCAL_NAME:
11525796c8dcSSimon Schubert       return is_ctor_dtor_or_conversion (d_right (dc));
11535796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CTOR:
11545796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_DTOR:
11555796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CAST:
11565796c8dcSSimon Schubert       return 1;
11575796c8dcSSimon Schubert     }
11585796c8dcSSimon Schubert }
11595796c8dcSSimon Schubert 
11605796c8dcSSimon Schubert /* <encoding> ::= <(function) name> <bare-function-type>
11615796c8dcSSimon Schubert               ::= <(data) name>
11625796c8dcSSimon Schubert               ::= <special-name>
11635796c8dcSSimon Schubert 
11645796c8dcSSimon Schubert    TOP_LEVEL is non-zero when called at the top level, in which case
11655796c8dcSSimon Schubert    if DMGL_PARAMS is not set we do not demangle the function
11665796c8dcSSimon Schubert    parameters.  We only set this at the top level, because otherwise
11675796c8dcSSimon Schubert    we would not correctly demangle names in local scopes.  */
11685796c8dcSSimon Schubert 
11695796c8dcSSimon Schubert static struct demangle_component *
d_encoding(struct d_info * di,int top_level)11705796c8dcSSimon Schubert d_encoding (struct d_info *di, int top_level)
11715796c8dcSSimon Schubert {
11725796c8dcSSimon Schubert   char peek = d_peek_char (di);
11735796c8dcSSimon Schubert 
11745796c8dcSSimon Schubert   if (peek == 'G' || peek == 'T')
11755796c8dcSSimon Schubert     return d_special_name (di);
11765796c8dcSSimon Schubert   else
11775796c8dcSSimon Schubert     {
11785796c8dcSSimon Schubert       struct demangle_component *dc;
11795796c8dcSSimon Schubert 
11805796c8dcSSimon Schubert       dc = d_name (di);
11815796c8dcSSimon Schubert 
11825796c8dcSSimon Schubert       if (dc != NULL && top_level && (di->options & DMGL_PARAMS) == 0)
11835796c8dcSSimon Schubert 	{
11845796c8dcSSimon Schubert 	  /* Strip off any initial CV-qualifiers, as they really apply
11855796c8dcSSimon Schubert 	     to the `this' parameter, and they were not output by the
11865796c8dcSSimon Schubert 	     v2 demangler without DMGL_PARAMS.  */
11875796c8dcSSimon Schubert 	  while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
11885796c8dcSSimon Schubert 		 || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
11895796c8dcSSimon Schubert 		 || dc->type == DEMANGLE_COMPONENT_CONST_THIS)
11905796c8dcSSimon Schubert 	    dc = d_left (dc);
11915796c8dcSSimon Schubert 
11925796c8dcSSimon Schubert 	  /* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then
11935796c8dcSSimon Schubert 	     there may be CV-qualifiers on its right argument which
11945796c8dcSSimon Schubert 	     really apply here; this happens when parsing a class
11955796c8dcSSimon Schubert 	     which is local to a function.  */
11965796c8dcSSimon Schubert 	  if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
11975796c8dcSSimon Schubert 	    {
11985796c8dcSSimon Schubert 	      struct demangle_component *dcr;
11995796c8dcSSimon Schubert 
12005796c8dcSSimon Schubert 	      dcr = d_right (dc);
12015796c8dcSSimon Schubert 	      while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS
12025796c8dcSSimon Schubert 		     || dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS
12035796c8dcSSimon Schubert 		     || dcr->type == DEMANGLE_COMPONENT_CONST_THIS)
12045796c8dcSSimon Schubert 		dcr = d_left (dcr);
12055796c8dcSSimon Schubert 	      dc->u.s_binary.right = dcr;
12065796c8dcSSimon Schubert 	    }
12075796c8dcSSimon Schubert 
12085796c8dcSSimon Schubert 	  return dc;
12095796c8dcSSimon Schubert 	}
12105796c8dcSSimon Schubert 
12115796c8dcSSimon Schubert       peek = d_peek_char (di);
12125796c8dcSSimon Schubert       if (dc == NULL || peek == '\0' || peek == 'E')
12135796c8dcSSimon Schubert 	return dc;
12145796c8dcSSimon Schubert       return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc,
12155796c8dcSSimon Schubert 			  d_bare_function_type (di, has_return_type (dc)));
12165796c8dcSSimon Schubert     }
12175796c8dcSSimon Schubert }
12185796c8dcSSimon Schubert 
1219*ef5ccd6cSJohn Marino /* <tagged-name> ::= <name> B <source-name> */
1220*ef5ccd6cSJohn Marino 
1221*ef5ccd6cSJohn Marino static struct demangle_component *
d_abi_tags(struct d_info * di,struct demangle_component * dc)1222*ef5ccd6cSJohn Marino d_abi_tags (struct d_info *di, struct demangle_component *dc)
1223*ef5ccd6cSJohn Marino {
1224*ef5ccd6cSJohn Marino   char peek;
1225*ef5ccd6cSJohn Marino   while (peek = d_peek_char (di),
1226*ef5ccd6cSJohn Marino 	 peek == 'B')
1227*ef5ccd6cSJohn Marino     {
1228*ef5ccd6cSJohn Marino       struct demangle_component *tag;
1229*ef5ccd6cSJohn Marino       d_advance (di, 1);
1230*ef5ccd6cSJohn Marino       tag = d_source_name (di);
1231*ef5ccd6cSJohn Marino       dc = d_make_comp (di, DEMANGLE_COMPONENT_TAGGED_NAME, dc, tag);
1232*ef5ccd6cSJohn Marino     }
1233*ef5ccd6cSJohn Marino   return dc;
1234*ef5ccd6cSJohn Marino }
1235*ef5ccd6cSJohn Marino 
12365796c8dcSSimon Schubert /* <name> ::= <nested-name>
12375796c8dcSSimon Schubert           ::= <unscoped-name>
12385796c8dcSSimon Schubert           ::= <unscoped-template-name> <template-args>
12395796c8dcSSimon Schubert           ::= <local-name>
12405796c8dcSSimon Schubert 
12415796c8dcSSimon Schubert    <unscoped-name> ::= <unqualified-name>
12425796c8dcSSimon Schubert                    ::= St <unqualified-name>
12435796c8dcSSimon Schubert 
12445796c8dcSSimon Schubert    <unscoped-template-name> ::= <unscoped-name>
12455796c8dcSSimon Schubert                             ::= <substitution>
12465796c8dcSSimon Schubert */
12475796c8dcSSimon Schubert 
12485796c8dcSSimon Schubert static struct demangle_component *
d_name(struct d_info * di)12495796c8dcSSimon Schubert d_name (struct d_info *di)
12505796c8dcSSimon Schubert {
12515796c8dcSSimon Schubert   char peek = d_peek_char (di);
12525796c8dcSSimon Schubert   struct demangle_component *dc;
12535796c8dcSSimon Schubert 
12545796c8dcSSimon Schubert   switch (peek)
12555796c8dcSSimon Schubert     {
12565796c8dcSSimon Schubert     case 'N':
12575796c8dcSSimon Schubert       return d_nested_name (di);
12585796c8dcSSimon Schubert 
12595796c8dcSSimon Schubert     case 'Z':
12605796c8dcSSimon Schubert       return d_local_name (di);
12615796c8dcSSimon Schubert 
12625796c8dcSSimon Schubert     case 'L':
1263cf7f2e2dSJohn Marino     case 'U':
12645796c8dcSSimon Schubert       return d_unqualified_name (di);
12655796c8dcSSimon Schubert 
12665796c8dcSSimon Schubert     case 'S':
12675796c8dcSSimon Schubert       {
12685796c8dcSSimon Schubert 	int subst;
12695796c8dcSSimon Schubert 
12705796c8dcSSimon Schubert 	if (d_peek_next_char (di) != 't')
12715796c8dcSSimon Schubert 	  {
12725796c8dcSSimon Schubert 	    dc = d_substitution (di, 0);
12735796c8dcSSimon Schubert 	    subst = 1;
12745796c8dcSSimon Schubert 	  }
12755796c8dcSSimon Schubert 	else
12765796c8dcSSimon Schubert 	  {
12775796c8dcSSimon Schubert 	    d_advance (di, 2);
12785796c8dcSSimon Schubert 	    dc = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME,
12795796c8dcSSimon Schubert 			      d_make_name (di, "std", 3),
12805796c8dcSSimon Schubert 			      d_unqualified_name (di));
12815796c8dcSSimon Schubert 	    di->expansion += 3;
12825796c8dcSSimon Schubert 	    subst = 0;
12835796c8dcSSimon Schubert 	  }
12845796c8dcSSimon Schubert 
12855796c8dcSSimon Schubert 	if (d_peek_char (di) != 'I')
12865796c8dcSSimon Schubert 	  {
12875796c8dcSSimon Schubert 	    /* The grammar does not permit this case to occur if we
12885796c8dcSSimon Schubert 	       called d_substitution() above (i.e., subst == 1).  We
12895796c8dcSSimon Schubert 	       don't bother to check.  */
12905796c8dcSSimon Schubert 	  }
12915796c8dcSSimon Schubert 	else
12925796c8dcSSimon Schubert 	  {
12935796c8dcSSimon Schubert 	    /* This is <template-args>, which means that we just saw
12945796c8dcSSimon Schubert 	       <unscoped-template-name>, which is a substitution
12955796c8dcSSimon Schubert 	       candidate if we didn't just get it from a
12965796c8dcSSimon Schubert 	       substitution.  */
12975796c8dcSSimon Schubert 	    if (! subst)
12985796c8dcSSimon Schubert 	      {
12995796c8dcSSimon Schubert 		if (! d_add_substitution (di, dc))
13005796c8dcSSimon Schubert 		  return NULL;
13015796c8dcSSimon Schubert 	      }
13025796c8dcSSimon Schubert 	    dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
13035796c8dcSSimon Schubert 			      d_template_args (di));
13045796c8dcSSimon Schubert 	  }
13055796c8dcSSimon Schubert 
13065796c8dcSSimon Schubert 	return dc;
13075796c8dcSSimon Schubert       }
13085796c8dcSSimon Schubert 
13095796c8dcSSimon Schubert     default:
13105796c8dcSSimon Schubert       dc = d_unqualified_name (di);
13115796c8dcSSimon Schubert       if (d_peek_char (di) == 'I')
13125796c8dcSSimon Schubert 	{
13135796c8dcSSimon Schubert 	  /* This is <template-args>, which means that we just saw
13145796c8dcSSimon Schubert 	     <unscoped-template-name>, which is a substitution
13155796c8dcSSimon Schubert 	     candidate.  */
13165796c8dcSSimon Schubert 	  if (! d_add_substitution (di, dc))
13175796c8dcSSimon Schubert 	    return NULL;
13185796c8dcSSimon Schubert 	  dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
13195796c8dcSSimon Schubert 			    d_template_args (di));
13205796c8dcSSimon Schubert 	}
13215796c8dcSSimon Schubert       return dc;
13225796c8dcSSimon Schubert     }
13235796c8dcSSimon Schubert }
13245796c8dcSSimon Schubert 
13255796c8dcSSimon Schubert /* <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
13265796c8dcSSimon Schubert                  ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
13275796c8dcSSimon Schubert */
13285796c8dcSSimon Schubert 
13295796c8dcSSimon Schubert static struct demangle_component *
d_nested_name(struct d_info * di)13305796c8dcSSimon Schubert d_nested_name (struct d_info *di)
13315796c8dcSSimon Schubert {
13325796c8dcSSimon Schubert   struct demangle_component *ret;
13335796c8dcSSimon Schubert   struct demangle_component **pret;
13345796c8dcSSimon Schubert 
13355796c8dcSSimon Schubert   if (! d_check_char (di, 'N'))
13365796c8dcSSimon Schubert     return NULL;
13375796c8dcSSimon Schubert 
13385796c8dcSSimon Schubert   pret = d_cv_qualifiers (di, &ret, 1);
13395796c8dcSSimon Schubert   if (pret == NULL)
13405796c8dcSSimon Schubert     return NULL;
13415796c8dcSSimon Schubert 
13425796c8dcSSimon Schubert   *pret = d_prefix (di);
13435796c8dcSSimon Schubert   if (*pret == NULL)
13445796c8dcSSimon Schubert     return NULL;
13455796c8dcSSimon Schubert 
13465796c8dcSSimon Schubert   if (! d_check_char (di, 'E'))
13475796c8dcSSimon Schubert     return NULL;
13485796c8dcSSimon Schubert 
13495796c8dcSSimon Schubert   return ret;
13505796c8dcSSimon Schubert }
13515796c8dcSSimon Schubert 
13525796c8dcSSimon Schubert /* <prefix> ::= <prefix> <unqualified-name>
13535796c8dcSSimon Schubert             ::= <template-prefix> <template-args>
13545796c8dcSSimon Schubert             ::= <template-param>
1355a45ae5f8SJohn Marino             ::= <decltype>
13565796c8dcSSimon Schubert             ::=
13575796c8dcSSimon Schubert             ::= <substitution>
13585796c8dcSSimon Schubert 
13595796c8dcSSimon Schubert    <template-prefix> ::= <prefix> <(template) unqualified-name>
13605796c8dcSSimon Schubert                      ::= <template-param>
13615796c8dcSSimon Schubert                      ::= <substitution>
13625796c8dcSSimon Schubert */
13635796c8dcSSimon Schubert 
13645796c8dcSSimon Schubert static struct demangle_component *
d_prefix(struct d_info * di)13655796c8dcSSimon Schubert d_prefix (struct d_info *di)
13665796c8dcSSimon Schubert {
13675796c8dcSSimon Schubert   struct demangle_component *ret = NULL;
13685796c8dcSSimon Schubert 
13695796c8dcSSimon Schubert   while (1)
13705796c8dcSSimon Schubert     {
13715796c8dcSSimon Schubert       char peek;
13725796c8dcSSimon Schubert       enum demangle_component_type comb_type;
13735796c8dcSSimon Schubert       struct demangle_component *dc;
13745796c8dcSSimon Schubert 
13755796c8dcSSimon Schubert       peek = d_peek_char (di);
13765796c8dcSSimon Schubert       if (peek == '\0')
13775796c8dcSSimon Schubert 	return NULL;
13785796c8dcSSimon Schubert 
13795796c8dcSSimon Schubert       /* The older code accepts a <local-name> here, but I don't see
13805796c8dcSSimon Schubert 	 that in the grammar.  The older code does not accept a
13815796c8dcSSimon Schubert 	 <template-param> here.  */
13825796c8dcSSimon Schubert 
13835796c8dcSSimon Schubert       comb_type = DEMANGLE_COMPONENT_QUAL_NAME;
1384a45ae5f8SJohn Marino       if (peek == 'D')
1385a45ae5f8SJohn Marino 	{
1386a45ae5f8SJohn Marino 	  char peek2 = d_peek_next_char (di);
1387a45ae5f8SJohn Marino 	  if (peek2 == 'T' || peek2 == 't')
1388a45ae5f8SJohn Marino 	    /* Decltype.  */
1389a45ae5f8SJohn Marino 	    dc = cplus_demangle_type (di);
1390a45ae5f8SJohn Marino 	  else
1391a45ae5f8SJohn Marino 	    /* Destructor name.  */
1392a45ae5f8SJohn Marino 	    dc = d_unqualified_name (di);
1393a45ae5f8SJohn Marino 	}
1394a45ae5f8SJohn Marino       else if (IS_DIGIT (peek)
13955796c8dcSSimon Schubert 	  || IS_LOWER (peek)
13965796c8dcSSimon Schubert 	  || peek == 'C'
1397cf7f2e2dSJohn Marino 	  || peek == 'U'
13985796c8dcSSimon Schubert 	  || peek == 'L')
13995796c8dcSSimon Schubert 	dc = d_unqualified_name (di);
14005796c8dcSSimon Schubert       else if (peek == 'S')
14015796c8dcSSimon Schubert 	dc = d_substitution (di, 1);
14025796c8dcSSimon Schubert       else if (peek == 'I')
14035796c8dcSSimon Schubert 	{
14045796c8dcSSimon Schubert 	  if (ret == NULL)
14055796c8dcSSimon Schubert 	    return NULL;
14065796c8dcSSimon Schubert 	  comb_type = DEMANGLE_COMPONENT_TEMPLATE;
14075796c8dcSSimon Schubert 	  dc = d_template_args (di);
14085796c8dcSSimon Schubert 	}
14095796c8dcSSimon Schubert       else if (peek == 'T')
14105796c8dcSSimon Schubert 	dc = d_template_param (di);
14115796c8dcSSimon Schubert       else if (peek == 'E')
14125796c8dcSSimon Schubert 	return ret;
1413cf7f2e2dSJohn Marino       else if (peek == 'M')
1414cf7f2e2dSJohn Marino 	{
1415cf7f2e2dSJohn Marino 	  /* Initializer scope for a lambda.  We don't need to represent
1416cf7f2e2dSJohn Marino 	     this; the normal code will just treat the variable as a type
1417cf7f2e2dSJohn Marino 	     scope, which gives appropriate output.  */
1418cf7f2e2dSJohn Marino 	  if (ret == NULL)
1419cf7f2e2dSJohn Marino 	    return NULL;
1420cf7f2e2dSJohn Marino 	  d_advance (di, 1);
1421cf7f2e2dSJohn Marino 	  continue;
1422cf7f2e2dSJohn Marino 	}
14235796c8dcSSimon Schubert       else
14245796c8dcSSimon Schubert 	return NULL;
14255796c8dcSSimon Schubert 
14265796c8dcSSimon Schubert       if (ret == NULL)
14275796c8dcSSimon Schubert 	ret = dc;
14285796c8dcSSimon Schubert       else
14295796c8dcSSimon Schubert 	ret = d_make_comp (di, comb_type, ret, dc);
14305796c8dcSSimon Schubert 
14315796c8dcSSimon Schubert       if (peek != 'S' && d_peek_char (di) != 'E')
14325796c8dcSSimon Schubert 	{
14335796c8dcSSimon Schubert 	  if (! d_add_substitution (di, ret))
14345796c8dcSSimon Schubert 	    return NULL;
14355796c8dcSSimon Schubert 	}
14365796c8dcSSimon Schubert     }
14375796c8dcSSimon Schubert }
14385796c8dcSSimon Schubert 
14395796c8dcSSimon Schubert /* <unqualified-name> ::= <operator-name>
14405796c8dcSSimon Schubert                       ::= <ctor-dtor-name>
14415796c8dcSSimon Schubert                       ::= <source-name>
14425796c8dcSSimon Schubert 		      ::= <local-source-name>
14435796c8dcSSimon Schubert 
14445796c8dcSSimon Schubert     <local-source-name>	::= L <source-name> <discriminator>
14455796c8dcSSimon Schubert */
14465796c8dcSSimon Schubert 
14475796c8dcSSimon Schubert static struct demangle_component *
d_unqualified_name(struct d_info * di)14485796c8dcSSimon Schubert d_unqualified_name (struct d_info *di)
14495796c8dcSSimon Schubert {
1450*ef5ccd6cSJohn Marino   struct demangle_component *ret;
14515796c8dcSSimon Schubert   char peek;
14525796c8dcSSimon Schubert 
14535796c8dcSSimon Schubert   peek = d_peek_char (di);
14545796c8dcSSimon Schubert   if (IS_DIGIT (peek))
1455*ef5ccd6cSJohn Marino     ret = d_source_name (di);
14565796c8dcSSimon Schubert   else if (IS_LOWER (peek))
14575796c8dcSSimon Schubert     {
14585796c8dcSSimon Schubert       ret = d_operator_name (di);
14595796c8dcSSimon Schubert       if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
1460*ef5ccd6cSJohn Marino 	{
14615796c8dcSSimon Schubert 	  di->expansion += sizeof "operator" + ret->u.s_operator.op->len - 2;
1462*ef5ccd6cSJohn Marino 	  if (!strcmp (ret->u.s_operator.op->code, "li"))
1463*ef5ccd6cSJohn Marino 	    ret = d_make_comp (di, DEMANGLE_COMPONENT_UNARY, ret,
1464*ef5ccd6cSJohn Marino 			       d_source_name (di));
1465*ef5ccd6cSJohn Marino 	}
14665796c8dcSSimon Schubert     }
14675796c8dcSSimon Schubert   else if (peek == 'C' || peek == 'D')
1468*ef5ccd6cSJohn Marino     ret = d_ctor_dtor_name (di);
14695796c8dcSSimon Schubert   else if (peek == 'L')
14705796c8dcSSimon Schubert     {
14715796c8dcSSimon Schubert       d_advance (di, 1);
14725796c8dcSSimon Schubert 
14735796c8dcSSimon Schubert       ret = d_source_name (di);
14745796c8dcSSimon Schubert       if (ret == NULL)
14755796c8dcSSimon Schubert 	return NULL;
14765796c8dcSSimon Schubert       if (! d_discriminator (di))
14775796c8dcSSimon Schubert 	return NULL;
14785796c8dcSSimon Schubert     }
1479cf7f2e2dSJohn Marino   else if (peek == 'U')
1480cf7f2e2dSJohn Marino     {
1481cf7f2e2dSJohn Marino       switch (d_peek_next_char (di))
1482cf7f2e2dSJohn Marino 	{
1483cf7f2e2dSJohn Marino 	case 'l':
1484*ef5ccd6cSJohn Marino 	  ret = d_lambda (di);
1485*ef5ccd6cSJohn Marino 	  break;
1486cf7f2e2dSJohn Marino 	case 't':
1487*ef5ccd6cSJohn Marino 	  ret = d_unnamed_type (di);
1488*ef5ccd6cSJohn Marino 	  break;
1489cf7f2e2dSJohn Marino 	default:
1490cf7f2e2dSJohn Marino 	  return NULL;
1491cf7f2e2dSJohn Marino 	}
1492cf7f2e2dSJohn Marino     }
14935796c8dcSSimon Schubert   else
14945796c8dcSSimon Schubert     return NULL;
1495*ef5ccd6cSJohn Marino 
1496*ef5ccd6cSJohn Marino   if (d_peek_char (di) == 'B')
1497*ef5ccd6cSJohn Marino     ret = d_abi_tags (di, ret);
1498*ef5ccd6cSJohn Marino   return ret;
14995796c8dcSSimon Schubert }
15005796c8dcSSimon Schubert 
15015796c8dcSSimon Schubert /* <source-name> ::= <(positive length) number> <identifier>  */
15025796c8dcSSimon Schubert 
15035796c8dcSSimon Schubert static struct demangle_component *
d_source_name(struct d_info * di)15045796c8dcSSimon Schubert d_source_name (struct d_info *di)
15055796c8dcSSimon Schubert {
15065796c8dcSSimon Schubert   long len;
15075796c8dcSSimon Schubert   struct demangle_component *ret;
15085796c8dcSSimon Schubert 
15095796c8dcSSimon Schubert   len = d_number (di);
15105796c8dcSSimon Schubert   if (len <= 0)
15115796c8dcSSimon Schubert     return NULL;
15125796c8dcSSimon Schubert   ret = d_identifier (di, len);
15135796c8dcSSimon Schubert   di->last_name = ret;
15145796c8dcSSimon Schubert   return ret;
15155796c8dcSSimon Schubert }
15165796c8dcSSimon Schubert 
15175796c8dcSSimon Schubert /* number ::= [n] <(non-negative decimal integer)>  */
15185796c8dcSSimon Schubert 
15195796c8dcSSimon Schubert static long
d_number(struct d_info * di)15205796c8dcSSimon Schubert d_number (struct d_info *di)
15215796c8dcSSimon Schubert {
15225796c8dcSSimon Schubert   int negative;
15235796c8dcSSimon Schubert   char peek;
15245796c8dcSSimon Schubert   long ret;
15255796c8dcSSimon Schubert 
15265796c8dcSSimon Schubert   negative = 0;
15275796c8dcSSimon Schubert   peek = d_peek_char (di);
15285796c8dcSSimon Schubert   if (peek == 'n')
15295796c8dcSSimon Schubert     {
15305796c8dcSSimon Schubert       negative = 1;
15315796c8dcSSimon Schubert       d_advance (di, 1);
15325796c8dcSSimon Schubert       peek = d_peek_char (di);
15335796c8dcSSimon Schubert     }
15345796c8dcSSimon Schubert 
15355796c8dcSSimon Schubert   ret = 0;
15365796c8dcSSimon Schubert   while (1)
15375796c8dcSSimon Schubert     {
15385796c8dcSSimon Schubert       if (! IS_DIGIT (peek))
15395796c8dcSSimon Schubert 	{
15405796c8dcSSimon Schubert 	  if (negative)
15415796c8dcSSimon Schubert 	    ret = - ret;
15425796c8dcSSimon Schubert 	  return ret;
15435796c8dcSSimon Schubert 	}
15445796c8dcSSimon Schubert       ret = ret * 10 + peek - '0';
15455796c8dcSSimon Schubert       d_advance (di, 1);
15465796c8dcSSimon Schubert       peek = d_peek_char (di);
15475796c8dcSSimon Schubert     }
15485796c8dcSSimon Schubert }
15495796c8dcSSimon Schubert 
1550cf7f2e2dSJohn Marino /* Like d_number, but returns a demangle_component.  */
1551cf7f2e2dSJohn Marino 
1552cf7f2e2dSJohn Marino static struct demangle_component *
d_number_component(struct d_info * di)1553cf7f2e2dSJohn Marino d_number_component (struct d_info *di)
1554cf7f2e2dSJohn Marino {
1555cf7f2e2dSJohn Marino   struct demangle_component *ret = d_make_empty (di);
1556cf7f2e2dSJohn Marino   if (ret)
1557cf7f2e2dSJohn Marino     {
1558cf7f2e2dSJohn Marino       ret->type = DEMANGLE_COMPONENT_NUMBER;
1559cf7f2e2dSJohn Marino       ret->u.s_number.number = d_number (di);
1560cf7f2e2dSJohn Marino     }
1561cf7f2e2dSJohn Marino   return ret;
1562cf7f2e2dSJohn Marino }
1563cf7f2e2dSJohn Marino 
15645796c8dcSSimon Schubert /* identifier ::= <(unqualified source code identifier)>  */
15655796c8dcSSimon Schubert 
15665796c8dcSSimon Schubert static struct demangle_component *
d_identifier(struct d_info * di,int len)15675796c8dcSSimon Schubert d_identifier (struct d_info *di, int len)
15685796c8dcSSimon Schubert {
15695796c8dcSSimon Schubert   const char *name;
15705796c8dcSSimon Schubert 
15715796c8dcSSimon Schubert   name = d_str (di);
15725796c8dcSSimon Schubert 
15735796c8dcSSimon Schubert   if (di->send - name < len)
15745796c8dcSSimon Schubert     return NULL;
15755796c8dcSSimon Schubert 
15765796c8dcSSimon Schubert   d_advance (di, len);
15775796c8dcSSimon Schubert 
15785796c8dcSSimon Schubert   /* A Java mangled name may have a trailing '$' if it is a C++
15795796c8dcSSimon Schubert      keyword.  This '$' is not included in the length count.  We just
15805796c8dcSSimon Schubert      ignore the '$'.  */
15815796c8dcSSimon Schubert   if ((di->options & DMGL_JAVA) != 0
15825796c8dcSSimon Schubert       && d_peek_char (di) == '$')
15835796c8dcSSimon Schubert     d_advance (di, 1);
15845796c8dcSSimon Schubert 
15855796c8dcSSimon Schubert   /* Look for something which looks like a gcc encoding of an
15865796c8dcSSimon Schubert      anonymous namespace, and replace it with a more user friendly
15875796c8dcSSimon Schubert      name.  */
15885796c8dcSSimon Schubert   if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2
15895796c8dcSSimon Schubert       && memcmp (name, ANONYMOUS_NAMESPACE_PREFIX,
15905796c8dcSSimon Schubert 		 ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0)
15915796c8dcSSimon Schubert     {
15925796c8dcSSimon Schubert       const char *s;
15935796c8dcSSimon Schubert 
15945796c8dcSSimon Schubert       s = name + ANONYMOUS_NAMESPACE_PREFIX_LEN;
15955796c8dcSSimon Schubert       if ((*s == '.' || *s == '_' || *s == '$')
15965796c8dcSSimon Schubert 	  && s[1] == 'N')
15975796c8dcSSimon Schubert 	{
15985796c8dcSSimon Schubert 	  di->expansion -= len - sizeof "(anonymous namespace)";
15995796c8dcSSimon Schubert 	  return d_make_name (di, "(anonymous namespace)",
16005796c8dcSSimon Schubert 			      sizeof "(anonymous namespace)" - 1);
16015796c8dcSSimon Schubert 	}
16025796c8dcSSimon Schubert     }
16035796c8dcSSimon Schubert 
16045796c8dcSSimon Schubert   return d_make_name (di, name, len);
16055796c8dcSSimon Schubert }
16065796c8dcSSimon Schubert 
16075796c8dcSSimon Schubert /* operator_name ::= many different two character encodings.
16085796c8dcSSimon Schubert                  ::= cv <type>
16095796c8dcSSimon Schubert                  ::= v <digit> <source-name>
1610*ef5ccd6cSJohn Marino 
1611*ef5ccd6cSJohn Marino    This list is sorted for binary search.  */
16125796c8dcSSimon Schubert 
16135796c8dcSSimon Schubert #define NL(s) s, (sizeof s) - 1
16145796c8dcSSimon Schubert 
16155796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
16165796c8dcSSimon Schubert const struct demangle_operator_info cplus_demangle_operators[] =
16175796c8dcSSimon Schubert {
16185796c8dcSSimon Schubert   { "aN", NL ("&="),        2 },
16195796c8dcSSimon Schubert   { "aS", NL ("="),         2 },
16205796c8dcSSimon Schubert   { "aa", NL ("&&"),        2 },
16215796c8dcSSimon Schubert   { "ad", NL ("&"),         1 },
16225796c8dcSSimon Schubert   { "an", NL ("&"),         2 },
1623*ef5ccd6cSJohn Marino   { "at", NL ("alignof "),   1 },
1624*ef5ccd6cSJohn Marino   { "az", NL ("alignof "),   1 },
1625*ef5ccd6cSJohn Marino   { "cc", NL ("const_cast"), 2 },
16265796c8dcSSimon Schubert   { "cl", NL ("()"),        2 },
16275796c8dcSSimon Schubert   { "cm", NL (","),         2 },
16285796c8dcSSimon Schubert   { "co", NL ("~"),         1 },
16295796c8dcSSimon Schubert   { "dV", NL ("/="),        2 },
16305796c8dcSSimon Schubert   { "da", NL ("delete[] "), 1 },
1631*ef5ccd6cSJohn Marino   { "dc", NL ("dynamic_cast"), 2 },
16325796c8dcSSimon Schubert   { "de", NL ("*"),         1 },
16335796c8dcSSimon Schubert   { "dl", NL ("delete "),   1 },
1634*ef5ccd6cSJohn Marino   { "ds", NL (".*"),        2 },
16355796c8dcSSimon Schubert   { "dt", NL ("."),         2 },
16365796c8dcSSimon Schubert   { "dv", NL ("/"),         2 },
16375796c8dcSSimon Schubert   { "eO", NL ("^="),        2 },
16385796c8dcSSimon Schubert   { "eo", NL ("^"),         2 },
16395796c8dcSSimon Schubert   { "eq", NL ("=="),        2 },
16405796c8dcSSimon Schubert   { "ge", NL (">="),        2 },
1641*ef5ccd6cSJohn Marino   { "gs", NL ("::"),	    1 },
16425796c8dcSSimon Schubert   { "gt", NL (">"),         2 },
16435796c8dcSSimon Schubert   { "ix", NL ("[]"),        2 },
16445796c8dcSSimon Schubert   { "lS", NL ("<<="),       2 },
16455796c8dcSSimon Schubert   { "le", NL ("<="),        2 },
1646*ef5ccd6cSJohn Marino   { "li", NL ("operator\"\" "), 1 },
16475796c8dcSSimon Schubert   { "ls", NL ("<<"),        2 },
16485796c8dcSSimon Schubert   { "lt", NL ("<"),         2 },
16495796c8dcSSimon Schubert   { "mI", NL ("-="),        2 },
16505796c8dcSSimon Schubert   { "mL", NL ("*="),        2 },
16515796c8dcSSimon Schubert   { "mi", NL ("-"),         2 },
16525796c8dcSSimon Schubert   { "ml", NL ("*"),         2 },
16535796c8dcSSimon Schubert   { "mm", NL ("--"),        1 },
1654*ef5ccd6cSJohn Marino   { "na", NL ("new[]"),     3 },
16555796c8dcSSimon Schubert   { "ne", NL ("!="),        2 },
16565796c8dcSSimon Schubert   { "ng", NL ("-"),         1 },
16575796c8dcSSimon Schubert   { "nt", NL ("!"),         1 },
1658*ef5ccd6cSJohn Marino   { "nw", NL ("new"),       3 },
16595796c8dcSSimon Schubert   { "oR", NL ("|="),        2 },
16605796c8dcSSimon Schubert   { "oo", NL ("||"),        2 },
16615796c8dcSSimon Schubert   { "or", NL ("|"),         2 },
16625796c8dcSSimon Schubert   { "pL", NL ("+="),        2 },
16635796c8dcSSimon Schubert   { "pl", NL ("+"),         2 },
16645796c8dcSSimon Schubert   { "pm", NL ("->*"),       2 },
16655796c8dcSSimon Schubert   { "pp", NL ("++"),        1 },
16665796c8dcSSimon Schubert   { "ps", NL ("+"),         1 },
16675796c8dcSSimon Schubert   { "pt", NL ("->"),        2 },
16685796c8dcSSimon Schubert   { "qu", NL ("?"),         3 },
16695796c8dcSSimon Schubert   { "rM", NL ("%="),        2 },
16705796c8dcSSimon Schubert   { "rS", NL (">>="),       2 },
1671*ef5ccd6cSJohn Marino   { "rc", NL ("reinterpret_cast"), 2 },
16725796c8dcSSimon Schubert   { "rm", NL ("%"),         2 },
16735796c8dcSSimon Schubert   { "rs", NL (">>"),        2 },
1674*ef5ccd6cSJohn Marino   { "sc", NL ("static_cast"), 2 },
16755796c8dcSSimon Schubert   { "st", NL ("sizeof "),   1 },
16765796c8dcSSimon Schubert   { "sz", NL ("sizeof "),   1 },
1677*ef5ccd6cSJohn Marino   { "tr", NL ("throw"),     0 },
1678*ef5ccd6cSJohn Marino   { "tw", NL ("throw "),    1 },
16795796c8dcSSimon Schubert   { NULL, NULL, 0,          0 }
16805796c8dcSSimon Schubert };
16815796c8dcSSimon Schubert 
16825796c8dcSSimon Schubert static struct demangle_component *
d_operator_name(struct d_info * di)16835796c8dcSSimon Schubert d_operator_name (struct d_info *di)
16845796c8dcSSimon Schubert {
16855796c8dcSSimon Schubert   char c1;
16865796c8dcSSimon Schubert   char c2;
16875796c8dcSSimon Schubert 
16885796c8dcSSimon Schubert   c1 = d_next_char (di);
16895796c8dcSSimon Schubert   c2 = d_next_char (di);
16905796c8dcSSimon Schubert   if (c1 == 'v' && IS_DIGIT (c2))
16915796c8dcSSimon Schubert     return d_make_extended_operator (di, c2 - '0', d_source_name (di));
16925796c8dcSSimon Schubert   else if (c1 == 'c' && c2 == 'v')
16935796c8dcSSimon Schubert     return d_make_comp (di, DEMANGLE_COMPONENT_CAST,
16945796c8dcSSimon Schubert 			cplus_demangle_type (di), NULL);
16955796c8dcSSimon Schubert   else
16965796c8dcSSimon Schubert     {
16975796c8dcSSimon Schubert       /* LOW is the inclusive lower bound.  */
16985796c8dcSSimon Schubert       int low = 0;
16995796c8dcSSimon Schubert       /* HIGH is the exclusive upper bound.  We subtract one to ignore
17005796c8dcSSimon Schubert 	 the sentinel at the end of the array.  */
17015796c8dcSSimon Schubert       int high = ((sizeof (cplus_demangle_operators)
17025796c8dcSSimon Schubert 		   / sizeof (cplus_demangle_operators[0]))
17035796c8dcSSimon Schubert 		  - 1);
17045796c8dcSSimon Schubert 
17055796c8dcSSimon Schubert       while (1)
17065796c8dcSSimon Schubert 	{
17075796c8dcSSimon Schubert 	  int i;
17085796c8dcSSimon Schubert 	  const struct demangle_operator_info *p;
17095796c8dcSSimon Schubert 
17105796c8dcSSimon Schubert 	  i = low + (high - low) / 2;
17115796c8dcSSimon Schubert 	  p = cplus_demangle_operators + i;
17125796c8dcSSimon Schubert 
17135796c8dcSSimon Schubert 	  if (c1 == p->code[0] && c2 == p->code[1])
17145796c8dcSSimon Schubert 	    return d_make_operator (di, p);
17155796c8dcSSimon Schubert 
17165796c8dcSSimon Schubert 	  if (c1 < p->code[0] || (c1 == p->code[0] && c2 < p->code[1]))
17175796c8dcSSimon Schubert 	    high = i;
17185796c8dcSSimon Schubert 	  else
17195796c8dcSSimon Schubert 	    low = i + 1;
17205796c8dcSSimon Schubert 	  if (low == high)
17215796c8dcSSimon Schubert 	    return NULL;
17225796c8dcSSimon Schubert 	}
17235796c8dcSSimon Schubert     }
17245796c8dcSSimon Schubert }
17255796c8dcSSimon Schubert 
17265796c8dcSSimon Schubert static struct demangle_component *
d_make_character(struct d_info * di,int c)17275796c8dcSSimon Schubert d_make_character (struct d_info *di, int c)
17285796c8dcSSimon Schubert {
17295796c8dcSSimon Schubert   struct demangle_component *p;
17305796c8dcSSimon Schubert   p = d_make_empty (di);
17315796c8dcSSimon Schubert   if (p != NULL)
17325796c8dcSSimon Schubert     {
17335796c8dcSSimon Schubert       p->type = DEMANGLE_COMPONENT_CHARACTER;
17345796c8dcSSimon Schubert       p->u.s_character.character = c;
17355796c8dcSSimon Schubert     }
17365796c8dcSSimon Schubert   return p;
17375796c8dcSSimon Schubert }
17385796c8dcSSimon Schubert 
17395796c8dcSSimon Schubert static struct demangle_component *
d_java_resource(struct d_info * di)17405796c8dcSSimon Schubert d_java_resource (struct d_info *di)
17415796c8dcSSimon Schubert {
17425796c8dcSSimon Schubert   struct demangle_component *p = NULL;
17435796c8dcSSimon Schubert   struct demangle_component *next = NULL;
17445796c8dcSSimon Schubert   long len, i;
17455796c8dcSSimon Schubert   char c;
17465796c8dcSSimon Schubert   const char *str;
17475796c8dcSSimon Schubert 
17485796c8dcSSimon Schubert   len = d_number (di);
17495796c8dcSSimon Schubert   if (len <= 1)
17505796c8dcSSimon Schubert     return NULL;
17515796c8dcSSimon Schubert 
17525796c8dcSSimon Schubert   /* Eat the leading '_'.  */
17535796c8dcSSimon Schubert   if (d_next_char (di) != '_')
17545796c8dcSSimon Schubert     return NULL;
17555796c8dcSSimon Schubert   len--;
17565796c8dcSSimon Schubert 
17575796c8dcSSimon Schubert   str = d_str (di);
17585796c8dcSSimon Schubert   i = 0;
17595796c8dcSSimon Schubert 
17605796c8dcSSimon Schubert   while (len > 0)
17615796c8dcSSimon Schubert     {
17625796c8dcSSimon Schubert       c = str[i];
17635796c8dcSSimon Schubert       if (!c)
17645796c8dcSSimon Schubert 	return NULL;
17655796c8dcSSimon Schubert 
17665796c8dcSSimon Schubert       /* Each chunk is either a '$' escape...  */
17675796c8dcSSimon Schubert       if (c == '$')
17685796c8dcSSimon Schubert 	{
17695796c8dcSSimon Schubert 	  i++;
17705796c8dcSSimon Schubert 	  switch (str[i++])
17715796c8dcSSimon Schubert 	    {
17725796c8dcSSimon Schubert 	    case 'S':
17735796c8dcSSimon Schubert 	      c = '/';
17745796c8dcSSimon Schubert 	      break;
17755796c8dcSSimon Schubert 	    case '_':
17765796c8dcSSimon Schubert 	      c = '.';
17775796c8dcSSimon Schubert 	      break;
17785796c8dcSSimon Schubert 	    case '$':
17795796c8dcSSimon Schubert 	      c = '$';
17805796c8dcSSimon Schubert 	      break;
17815796c8dcSSimon Schubert 	    default:
17825796c8dcSSimon Schubert 	      return NULL;
17835796c8dcSSimon Schubert 	    }
17845796c8dcSSimon Schubert 	  next = d_make_character (di, c);
17855796c8dcSSimon Schubert 	  d_advance (di, i);
17865796c8dcSSimon Schubert 	  str = d_str (di);
17875796c8dcSSimon Schubert 	  len -= i;
17885796c8dcSSimon Schubert 	  i = 0;
17895796c8dcSSimon Schubert 	  if (next == NULL)
17905796c8dcSSimon Schubert 	    return NULL;
17915796c8dcSSimon Schubert 	}
17925796c8dcSSimon Schubert       /* ... or a sequence of characters.  */
17935796c8dcSSimon Schubert       else
17945796c8dcSSimon Schubert 	{
17955796c8dcSSimon Schubert 	  while (i < len && str[i] && str[i] != '$')
17965796c8dcSSimon Schubert 	    i++;
17975796c8dcSSimon Schubert 
17985796c8dcSSimon Schubert 	  next = d_make_name (di, str, i);
17995796c8dcSSimon Schubert 	  d_advance (di, i);
18005796c8dcSSimon Schubert 	  str = d_str (di);
18015796c8dcSSimon Schubert 	  len -= i;
18025796c8dcSSimon Schubert 	  i = 0;
18035796c8dcSSimon Schubert 	  if (next == NULL)
18045796c8dcSSimon Schubert 	    return NULL;
18055796c8dcSSimon Schubert 	}
18065796c8dcSSimon Schubert 
18075796c8dcSSimon Schubert       if (p == NULL)
18085796c8dcSSimon Schubert 	p = next;
18095796c8dcSSimon Schubert       else
18105796c8dcSSimon Schubert 	{
18115796c8dcSSimon Schubert 	  p = d_make_comp (di, DEMANGLE_COMPONENT_COMPOUND_NAME, p, next);
18125796c8dcSSimon Schubert 	  if (p == NULL)
18135796c8dcSSimon Schubert 	    return NULL;
18145796c8dcSSimon Schubert 	}
18155796c8dcSSimon Schubert     }
18165796c8dcSSimon Schubert 
18175796c8dcSSimon Schubert   p = d_make_comp (di, DEMANGLE_COMPONENT_JAVA_RESOURCE, p, NULL);
18185796c8dcSSimon Schubert 
18195796c8dcSSimon Schubert   return p;
18205796c8dcSSimon Schubert }
18215796c8dcSSimon Schubert 
18225796c8dcSSimon Schubert /* <special-name> ::= TV <type>
18235796c8dcSSimon Schubert                   ::= TT <type>
18245796c8dcSSimon Schubert                   ::= TI <type>
18255796c8dcSSimon Schubert                   ::= TS <type>
18265796c8dcSSimon Schubert                   ::= GV <(object) name>
18275796c8dcSSimon Schubert                   ::= T <call-offset> <(base) encoding>
18285796c8dcSSimon Schubert                   ::= Tc <call-offset> <call-offset> <(base) encoding>
18295796c8dcSSimon Schubert    Also g++ extensions:
18305796c8dcSSimon Schubert                   ::= TC <type> <(offset) number> _ <(base) type>
18315796c8dcSSimon Schubert                   ::= TF <type>
18325796c8dcSSimon Schubert                   ::= TJ <type>
18335796c8dcSSimon Schubert                   ::= GR <name>
18345796c8dcSSimon Schubert 		  ::= GA <encoding>
18355796c8dcSSimon Schubert 		  ::= Gr <resource name>
1836a45ae5f8SJohn Marino 		  ::= GTt <encoding>
1837a45ae5f8SJohn Marino 		  ::= GTn <encoding>
18385796c8dcSSimon Schubert */
18395796c8dcSSimon Schubert 
18405796c8dcSSimon Schubert static struct demangle_component *
d_special_name(struct d_info * di)18415796c8dcSSimon Schubert d_special_name (struct d_info *di)
18425796c8dcSSimon Schubert {
18435796c8dcSSimon Schubert   di->expansion += 20;
18445796c8dcSSimon Schubert   if (d_check_char (di, 'T'))
18455796c8dcSSimon Schubert     {
18465796c8dcSSimon Schubert       switch (d_next_char (di))
18475796c8dcSSimon Schubert 	{
18485796c8dcSSimon Schubert 	case 'V':
18495796c8dcSSimon Schubert 	  di->expansion -= 5;
18505796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_VTABLE,
18515796c8dcSSimon Schubert 			      cplus_demangle_type (di), NULL);
18525796c8dcSSimon Schubert 	case 'T':
18535796c8dcSSimon Schubert 	  di->expansion -= 10;
18545796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_VTT,
18555796c8dcSSimon Schubert 			      cplus_demangle_type (di), NULL);
18565796c8dcSSimon Schubert 	case 'I':
18575796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO,
18585796c8dcSSimon Schubert 			      cplus_demangle_type (di), NULL);
18595796c8dcSSimon Schubert 	case 'S':
18605796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_NAME,
18615796c8dcSSimon Schubert 			      cplus_demangle_type (di), NULL);
18625796c8dcSSimon Schubert 
18635796c8dcSSimon Schubert 	case 'h':
18645796c8dcSSimon Schubert 	  if (! d_call_offset (di, 'h'))
18655796c8dcSSimon Schubert 	    return NULL;
18665796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_THUNK,
18675796c8dcSSimon Schubert 			      d_encoding (di, 0), NULL);
18685796c8dcSSimon Schubert 
18695796c8dcSSimon Schubert 	case 'v':
18705796c8dcSSimon Schubert 	  if (! d_call_offset (di, 'v'))
18715796c8dcSSimon Schubert 	    return NULL;
18725796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_VIRTUAL_THUNK,
18735796c8dcSSimon Schubert 			      d_encoding (di, 0), NULL);
18745796c8dcSSimon Schubert 
18755796c8dcSSimon Schubert 	case 'c':
18765796c8dcSSimon Schubert 	  if (! d_call_offset (di, '\0'))
18775796c8dcSSimon Schubert 	    return NULL;
18785796c8dcSSimon Schubert 	  if (! d_call_offset (di, '\0'))
18795796c8dcSSimon Schubert 	    return NULL;
18805796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_COVARIANT_THUNK,
18815796c8dcSSimon Schubert 			      d_encoding (di, 0), NULL);
18825796c8dcSSimon Schubert 
18835796c8dcSSimon Schubert 	case 'C':
18845796c8dcSSimon Schubert 	  {
18855796c8dcSSimon Schubert 	    struct demangle_component *derived_type;
18865796c8dcSSimon Schubert 	    long offset;
18875796c8dcSSimon Schubert 	    struct demangle_component *base_type;
18885796c8dcSSimon Schubert 
18895796c8dcSSimon Schubert 	    derived_type = cplus_demangle_type (di);
18905796c8dcSSimon Schubert 	    offset = d_number (di);
18915796c8dcSSimon Schubert 	    if (offset < 0)
18925796c8dcSSimon Schubert 	      return NULL;
18935796c8dcSSimon Schubert 	    if (! d_check_char (di, '_'))
18945796c8dcSSimon Schubert 	      return NULL;
18955796c8dcSSimon Schubert 	    base_type = cplus_demangle_type (di);
18965796c8dcSSimon Schubert 	    /* We don't display the offset.  FIXME: We should display
18975796c8dcSSimon Schubert 	       it in verbose mode.  */
18985796c8dcSSimon Schubert 	    di->expansion += 5;
18995796c8dcSSimon Schubert 	    return d_make_comp (di, DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
19005796c8dcSSimon Schubert 				base_type, derived_type);
19015796c8dcSSimon Schubert 	  }
19025796c8dcSSimon Schubert 
19035796c8dcSSimon Schubert 	case 'F':
19045796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_FN,
19055796c8dcSSimon Schubert 			      cplus_demangle_type (di), NULL);
19065796c8dcSSimon Schubert 	case 'J':
19075796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_JAVA_CLASS,
19085796c8dcSSimon Schubert 			      cplus_demangle_type (di), NULL);
19095796c8dcSSimon Schubert 
1910*ef5ccd6cSJohn Marino 	case 'H':
1911*ef5ccd6cSJohn Marino 	  return d_make_comp (di, DEMANGLE_COMPONENT_TLS_INIT,
1912*ef5ccd6cSJohn Marino 			      d_name (di), NULL);
1913*ef5ccd6cSJohn Marino 
1914*ef5ccd6cSJohn Marino 	case 'W':
1915*ef5ccd6cSJohn Marino 	  return d_make_comp (di, DEMANGLE_COMPONENT_TLS_WRAPPER,
1916*ef5ccd6cSJohn Marino 			      d_name (di), NULL);
1917*ef5ccd6cSJohn Marino 
19185796c8dcSSimon Schubert 	default:
19195796c8dcSSimon Schubert 	  return NULL;
19205796c8dcSSimon Schubert 	}
19215796c8dcSSimon Schubert     }
19225796c8dcSSimon Schubert   else if (d_check_char (di, 'G'))
19235796c8dcSSimon Schubert     {
19245796c8dcSSimon Schubert       switch (d_next_char (di))
19255796c8dcSSimon Schubert 	{
19265796c8dcSSimon Schubert 	case 'V':
19275796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, d_name (di), NULL);
19285796c8dcSSimon Schubert 
19295796c8dcSSimon Schubert 	case 'R':
1930a45ae5f8SJohn Marino 	  {
1931a45ae5f8SJohn Marino 	    struct demangle_component *name = d_name (di);
1932a45ae5f8SJohn Marino 	    return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, name,
1933a45ae5f8SJohn Marino 				d_number_component (di));
1934a45ae5f8SJohn Marino 	  }
19355796c8dcSSimon Schubert 
19365796c8dcSSimon Schubert 	case 'A':
19375796c8dcSSimon Schubert 	  return d_make_comp (di, DEMANGLE_COMPONENT_HIDDEN_ALIAS,
19385796c8dcSSimon Schubert 			      d_encoding (di, 0), NULL);
19395796c8dcSSimon Schubert 
1940a45ae5f8SJohn Marino 	case 'T':
1941a45ae5f8SJohn Marino 	  switch (d_next_char (di))
1942a45ae5f8SJohn Marino 	    {
1943a45ae5f8SJohn Marino 	    case 'n':
1944a45ae5f8SJohn Marino 	      return d_make_comp (di, DEMANGLE_COMPONENT_NONTRANSACTION_CLONE,
1945a45ae5f8SJohn Marino 				  d_encoding (di, 0), NULL);
1946a45ae5f8SJohn Marino 	    default:
1947a45ae5f8SJohn Marino 	      /* ??? The proposal is that other letters (such as 'h') stand
1948a45ae5f8SJohn Marino 		 for different variants of transaction cloning, such as
1949a45ae5f8SJohn Marino 		 compiling directly for hardware transaction support.  But
1950a45ae5f8SJohn Marino 		 they still should all be transactional clones of some sort
1951a45ae5f8SJohn Marino 		 so go ahead and call them that.  */
1952a45ae5f8SJohn Marino 	    case 't':
1953a45ae5f8SJohn Marino 	      return d_make_comp (di, DEMANGLE_COMPONENT_TRANSACTION_CLONE,
1954a45ae5f8SJohn Marino 				  d_encoding (di, 0), NULL);
1955a45ae5f8SJohn Marino 	    }
1956a45ae5f8SJohn Marino 
19575796c8dcSSimon Schubert 	case 'r':
19585796c8dcSSimon Schubert 	  return d_java_resource (di);
19595796c8dcSSimon Schubert 
19605796c8dcSSimon Schubert 	default:
19615796c8dcSSimon Schubert 	  return NULL;
19625796c8dcSSimon Schubert 	}
19635796c8dcSSimon Schubert     }
19645796c8dcSSimon Schubert   else
19655796c8dcSSimon Schubert     return NULL;
19665796c8dcSSimon Schubert }
19675796c8dcSSimon Schubert 
19685796c8dcSSimon Schubert /* <call-offset> ::= h <nv-offset> _
19695796c8dcSSimon Schubert                  ::= v <v-offset> _
19705796c8dcSSimon Schubert 
19715796c8dcSSimon Schubert    <nv-offset> ::= <(offset) number>
19725796c8dcSSimon Schubert 
19735796c8dcSSimon Schubert    <v-offset> ::= <(offset) number> _ <(virtual offset) number>
19745796c8dcSSimon Schubert 
19755796c8dcSSimon Schubert    The C parameter, if not '\0', is a character we just read which is
19765796c8dcSSimon Schubert    the start of the <call-offset>.
19775796c8dcSSimon Schubert 
19785796c8dcSSimon Schubert    We don't display the offset information anywhere.  FIXME: We should
19795796c8dcSSimon Schubert    display it in verbose mode.  */
19805796c8dcSSimon Schubert 
19815796c8dcSSimon Schubert static int
d_call_offset(struct d_info * di,int c)19825796c8dcSSimon Schubert d_call_offset (struct d_info *di, int c)
19835796c8dcSSimon Schubert {
19845796c8dcSSimon Schubert   if (c == '\0')
19855796c8dcSSimon Schubert     c = d_next_char (di);
19865796c8dcSSimon Schubert 
19875796c8dcSSimon Schubert   if (c == 'h')
19885796c8dcSSimon Schubert     d_number (di);
19895796c8dcSSimon Schubert   else if (c == 'v')
19905796c8dcSSimon Schubert     {
19915796c8dcSSimon Schubert       d_number (di);
19925796c8dcSSimon Schubert       if (! d_check_char (di, '_'))
19935796c8dcSSimon Schubert 	return 0;
19945796c8dcSSimon Schubert       d_number (di);
19955796c8dcSSimon Schubert     }
19965796c8dcSSimon Schubert   else
19975796c8dcSSimon Schubert     return 0;
19985796c8dcSSimon Schubert 
19995796c8dcSSimon Schubert   if (! d_check_char (di, '_'))
20005796c8dcSSimon Schubert     return 0;
20015796c8dcSSimon Schubert 
20025796c8dcSSimon Schubert   return 1;
20035796c8dcSSimon Schubert }
20045796c8dcSSimon Schubert 
20055796c8dcSSimon Schubert /* <ctor-dtor-name> ::= C1
20065796c8dcSSimon Schubert                     ::= C2
20075796c8dcSSimon Schubert                     ::= C3
20085796c8dcSSimon Schubert                     ::= D0
20095796c8dcSSimon Schubert                     ::= D1
20105796c8dcSSimon Schubert                     ::= D2
20115796c8dcSSimon Schubert */
20125796c8dcSSimon Schubert 
20135796c8dcSSimon Schubert static struct demangle_component *
d_ctor_dtor_name(struct d_info * di)20145796c8dcSSimon Schubert d_ctor_dtor_name (struct d_info *di)
20155796c8dcSSimon Schubert {
20165796c8dcSSimon Schubert   if (di->last_name != NULL)
20175796c8dcSSimon Schubert     {
20185796c8dcSSimon Schubert       if (di->last_name->type == DEMANGLE_COMPONENT_NAME)
20195796c8dcSSimon Schubert 	di->expansion += di->last_name->u.s_name.len;
20205796c8dcSSimon Schubert       else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD)
20215796c8dcSSimon Schubert 	di->expansion += di->last_name->u.s_string.len;
20225796c8dcSSimon Schubert     }
20235796c8dcSSimon Schubert   switch (d_peek_char (di))
20245796c8dcSSimon Schubert     {
20255796c8dcSSimon Schubert     case 'C':
20265796c8dcSSimon Schubert       {
20275796c8dcSSimon Schubert 	enum gnu_v3_ctor_kinds kind;
20285796c8dcSSimon Schubert 
20295796c8dcSSimon Schubert 	switch (d_peek_next_char (di))
20305796c8dcSSimon Schubert 	  {
20315796c8dcSSimon Schubert 	  case '1':
20325796c8dcSSimon Schubert 	    kind = gnu_v3_complete_object_ctor;
20335796c8dcSSimon Schubert 	    break;
20345796c8dcSSimon Schubert 	  case '2':
20355796c8dcSSimon Schubert 	    kind = gnu_v3_base_object_ctor;
20365796c8dcSSimon Schubert 	    break;
20375796c8dcSSimon Schubert 	  case '3':
20385796c8dcSSimon Schubert 	    kind = gnu_v3_complete_object_allocating_ctor;
20395796c8dcSSimon Schubert 	    break;
2040a45ae5f8SJohn Marino 	  case '5':
2041a45ae5f8SJohn Marino 	    kind = gnu_v3_object_ctor_group;
2042a45ae5f8SJohn Marino 	    break;
20435796c8dcSSimon Schubert 	  default:
20445796c8dcSSimon Schubert 	    return NULL;
20455796c8dcSSimon Schubert 	  }
20465796c8dcSSimon Schubert 	d_advance (di, 2);
20475796c8dcSSimon Schubert 	return d_make_ctor (di, kind, di->last_name);
20485796c8dcSSimon Schubert       }
20495796c8dcSSimon Schubert 
20505796c8dcSSimon Schubert     case 'D':
20515796c8dcSSimon Schubert       {
20525796c8dcSSimon Schubert 	enum gnu_v3_dtor_kinds kind;
20535796c8dcSSimon Schubert 
20545796c8dcSSimon Schubert 	switch (d_peek_next_char (di))
20555796c8dcSSimon Schubert 	  {
20565796c8dcSSimon Schubert 	  case '0':
20575796c8dcSSimon Schubert 	    kind = gnu_v3_deleting_dtor;
20585796c8dcSSimon Schubert 	    break;
20595796c8dcSSimon Schubert 	  case '1':
20605796c8dcSSimon Schubert 	    kind = gnu_v3_complete_object_dtor;
20615796c8dcSSimon Schubert 	    break;
20625796c8dcSSimon Schubert 	  case '2':
20635796c8dcSSimon Schubert 	    kind = gnu_v3_base_object_dtor;
20645796c8dcSSimon Schubert 	    break;
2065a45ae5f8SJohn Marino 	  case '5':
2066a45ae5f8SJohn Marino 	    kind = gnu_v3_object_dtor_group;
2067a45ae5f8SJohn Marino 	    break;
20685796c8dcSSimon Schubert 	  default:
20695796c8dcSSimon Schubert 	    return NULL;
20705796c8dcSSimon Schubert 	  }
20715796c8dcSSimon Schubert 	d_advance (di, 2);
20725796c8dcSSimon Schubert 	return d_make_dtor (di, kind, di->last_name);
20735796c8dcSSimon Schubert       }
20745796c8dcSSimon Schubert 
20755796c8dcSSimon Schubert     default:
20765796c8dcSSimon Schubert       return NULL;
20775796c8dcSSimon Schubert     }
20785796c8dcSSimon Schubert }
20795796c8dcSSimon Schubert 
20805796c8dcSSimon Schubert /* <type> ::= <builtin-type>
20815796c8dcSSimon Schubert           ::= <function-type>
20825796c8dcSSimon Schubert           ::= <class-enum-type>
20835796c8dcSSimon Schubert           ::= <array-type>
20845796c8dcSSimon Schubert           ::= <pointer-to-member-type>
20855796c8dcSSimon Schubert           ::= <template-param>
20865796c8dcSSimon Schubert           ::= <template-template-param> <template-args>
20875796c8dcSSimon Schubert           ::= <substitution>
20885796c8dcSSimon Schubert           ::= <CV-qualifiers> <type>
20895796c8dcSSimon Schubert           ::= P <type>
20905796c8dcSSimon Schubert           ::= R <type>
20915796c8dcSSimon Schubert           ::= O <type> (C++0x)
20925796c8dcSSimon Schubert           ::= C <type>
20935796c8dcSSimon Schubert           ::= G <type>
20945796c8dcSSimon Schubert           ::= U <source-name> <type>
20955796c8dcSSimon Schubert 
20965796c8dcSSimon Schubert    <builtin-type> ::= various one letter codes
20975796c8dcSSimon Schubert                   ::= u <source-name>
20985796c8dcSSimon Schubert */
20995796c8dcSSimon Schubert 
21005796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
21015796c8dcSSimon Schubert const struct demangle_builtin_type_info
21025796c8dcSSimon Schubert cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] =
21035796c8dcSSimon Schubert {
21045796c8dcSSimon Schubert   /* a */ { NL ("signed char"),	NL ("signed char"),	D_PRINT_DEFAULT },
21055796c8dcSSimon Schubert   /* b */ { NL ("bool"),	NL ("boolean"),		D_PRINT_BOOL },
21065796c8dcSSimon Schubert   /* c */ { NL ("char"),	NL ("byte"),		D_PRINT_DEFAULT },
21075796c8dcSSimon Schubert   /* d */ { NL ("double"),	NL ("double"),		D_PRINT_FLOAT },
21085796c8dcSSimon Schubert   /* e */ { NL ("long double"),	NL ("long double"),	D_PRINT_FLOAT },
21095796c8dcSSimon Schubert   /* f */ { NL ("float"),	NL ("float"),		D_PRINT_FLOAT },
21105796c8dcSSimon Schubert   /* g */ { NL ("__float128"),	NL ("__float128"),	D_PRINT_FLOAT },
21115796c8dcSSimon Schubert   /* h */ { NL ("unsigned char"), NL ("unsigned char"),	D_PRINT_DEFAULT },
21125796c8dcSSimon Schubert   /* i */ { NL ("int"),		NL ("int"),		D_PRINT_INT },
21135796c8dcSSimon Schubert   /* j */ { NL ("unsigned int"), NL ("unsigned"),	D_PRINT_UNSIGNED },
21145796c8dcSSimon Schubert   /* k */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
21155796c8dcSSimon Schubert   /* l */ { NL ("long"),	NL ("long"),		D_PRINT_LONG },
21165796c8dcSSimon Schubert   /* m */ { NL ("unsigned long"), NL ("unsigned long"),	D_PRINT_UNSIGNED_LONG },
21175796c8dcSSimon Schubert   /* n */ { NL ("__int128"),	NL ("__int128"),	D_PRINT_DEFAULT },
21185796c8dcSSimon Schubert   /* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"),
21195796c8dcSSimon Schubert 	    D_PRINT_DEFAULT },
21205796c8dcSSimon Schubert   /* p */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
21215796c8dcSSimon Schubert   /* q */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
21225796c8dcSSimon Schubert   /* r */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
21235796c8dcSSimon Schubert   /* s */ { NL ("short"),	NL ("short"),		D_PRINT_DEFAULT },
21245796c8dcSSimon Schubert   /* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT },
21255796c8dcSSimon Schubert   /* u */ { NULL, 0,		NULL, 0,		D_PRINT_DEFAULT },
21265796c8dcSSimon Schubert   /* v */ { NL ("void"),	NL ("void"),		D_PRINT_VOID },
21275796c8dcSSimon Schubert   /* w */ { NL ("wchar_t"),	NL ("char"),		D_PRINT_DEFAULT },
21285796c8dcSSimon Schubert   /* x */ { NL ("long long"),	NL ("long"),		D_PRINT_LONG_LONG },
21295796c8dcSSimon Schubert   /* y */ { NL ("unsigned long long"), NL ("unsigned long long"),
21305796c8dcSSimon Schubert 	    D_PRINT_UNSIGNED_LONG_LONG },
21315796c8dcSSimon Schubert   /* z */ { NL ("..."),		NL ("..."),		D_PRINT_DEFAULT },
21325796c8dcSSimon Schubert   /* 26 */ { NL ("decimal32"),	NL ("decimal32"),	D_PRINT_DEFAULT },
21335796c8dcSSimon Schubert   /* 27 */ { NL ("decimal64"),	NL ("decimal64"),	D_PRINT_DEFAULT },
21345796c8dcSSimon Schubert   /* 28 */ { NL ("decimal128"),	NL ("decimal128"),	D_PRINT_DEFAULT },
21355796c8dcSSimon Schubert   /* 29 */ { NL ("half"),	NL ("half"),		D_PRINT_FLOAT },
21365796c8dcSSimon Schubert   /* 30 */ { NL ("char16_t"),	NL ("char16_t"),	D_PRINT_DEFAULT },
21375796c8dcSSimon Schubert   /* 31 */ { NL ("char32_t"),	NL ("char32_t"),	D_PRINT_DEFAULT },
2138cf7f2e2dSJohn Marino   /* 32 */ { NL ("decltype(nullptr)"),	NL ("decltype(nullptr)"),
2139cf7f2e2dSJohn Marino 	     D_PRINT_DEFAULT },
21405796c8dcSSimon Schubert };
21415796c8dcSSimon Schubert 
21425796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
21435796c8dcSSimon Schubert struct demangle_component *
cplus_demangle_type(struct d_info * di)21445796c8dcSSimon Schubert cplus_demangle_type (struct d_info *di)
21455796c8dcSSimon Schubert {
21465796c8dcSSimon Schubert   char peek;
21475796c8dcSSimon Schubert   struct demangle_component *ret;
21485796c8dcSSimon Schubert   int can_subst;
21495796c8dcSSimon Schubert 
21505796c8dcSSimon Schubert   /* The ABI specifies that when CV-qualifiers are used, the base type
21515796c8dcSSimon Schubert      is substitutable, and the fully qualified type is substitutable,
21525796c8dcSSimon Schubert      but the base type with a strict subset of the CV-qualifiers is
21535796c8dcSSimon Schubert      not substitutable.  The natural recursive implementation of the
21545796c8dcSSimon Schubert      CV-qualifiers would cause subsets to be substitutable, so instead
21555796c8dcSSimon Schubert      we pull them all off now.
21565796c8dcSSimon Schubert 
21575796c8dcSSimon Schubert      FIXME: The ABI says that order-insensitive vendor qualifiers
21585796c8dcSSimon Schubert      should be handled in the same way, but we have no way to tell
21595796c8dcSSimon Schubert      which vendor qualifiers are order-insensitive and which are
21605796c8dcSSimon Schubert      order-sensitive.  So we just assume that they are all
21615796c8dcSSimon Schubert      order-sensitive.  g++ 3.4 supports only one vendor qualifier,
21625796c8dcSSimon Schubert      __vector, and it treats it as order-sensitive when mangling
21635796c8dcSSimon Schubert      names.  */
21645796c8dcSSimon Schubert 
21655796c8dcSSimon Schubert   peek = d_peek_char (di);
21665796c8dcSSimon Schubert   if (peek == 'r' || peek == 'V' || peek == 'K')
21675796c8dcSSimon Schubert     {
21685796c8dcSSimon Schubert       struct demangle_component **pret;
21695796c8dcSSimon Schubert 
21705796c8dcSSimon Schubert       pret = d_cv_qualifiers (di, &ret, 0);
21715796c8dcSSimon Schubert       if (pret == NULL)
21725796c8dcSSimon Schubert 	return NULL;
21735796c8dcSSimon Schubert       *pret = cplus_demangle_type (di);
21745796c8dcSSimon Schubert       if (! *pret || ! d_add_substitution (di, ret))
21755796c8dcSSimon Schubert 	return NULL;
21765796c8dcSSimon Schubert       return ret;
21775796c8dcSSimon Schubert     }
21785796c8dcSSimon Schubert 
21795796c8dcSSimon Schubert   can_subst = 1;
21805796c8dcSSimon Schubert 
21815796c8dcSSimon Schubert   switch (peek)
21825796c8dcSSimon Schubert     {
21835796c8dcSSimon Schubert     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
21845796c8dcSSimon Schubert     case 'h': case 'i': case 'j':           case 'l': case 'm': case 'n':
21855796c8dcSSimon Schubert     case 'o':                               case 's': case 't':
21865796c8dcSSimon Schubert     case 'v': case 'w': case 'x': case 'y': case 'z':
21875796c8dcSSimon Schubert       ret = d_make_builtin_type (di,
21885796c8dcSSimon Schubert 				 &cplus_demangle_builtin_types[peek - 'a']);
21895796c8dcSSimon Schubert       di->expansion += ret->u.s_builtin.type->len;
21905796c8dcSSimon Schubert       can_subst = 0;
21915796c8dcSSimon Schubert       d_advance (di, 1);
21925796c8dcSSimon Schubert       break;
21935796c8dcSSimon Schubert 
21945796c8dcSSimon Schubert     case 'u':
21955796c8dcSSimon Schubert       d_advance (di, 1);
21965796c8dcSSimon Schubert       ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE,
21975796c8dcSSimon Schubert 			 d_source_name (di), NULL);
21985796c8dcSSimon Schubert       break;
21995796c8dcSSimon Schubert 
22005796c8dcSSimon Schubert     case 'F':
22015796c8dcSSimon Schubert       ret = d_function_type (di);
22025796c8dcSSimon Schubert       break;
22035796c8dcSSimon Schubert 
22045796c8dcSSimon Schubert     case '0': case '1': case '2': case '3': case '4':
22055796c8dcSSimon Schubert     case '5': case '6': case '7': case '8': case '9':
22065796c8dcSSimon Schubert     case 'N':
22075796c8dcSSimon Schubert     case 'Z':
22085796c8dcSSimon Schubert       ret = d_class_enum_type (di);
22095796c8dcSSimon Schubert       break;
22105796c8dcSSimon Schubert 
22115796c8dcSSimon Schubert     case 'A':
22125796c8dcSSimon Schubert       ret = d_array_type (di);
22135796c8dcSSimon Schubert       break;
22145796c8dcSSimon Schubert 
22155796c8dcSSimon Schubert     case 'M':
22165796c8dcSSimon Schubert       ret = d_pointer_to_member_type (di);
22175796c8dcSSimon Schubert       break;
22185796c8dcSSimon Schubert 
22195796c8dcSSimon Schubert     case 'T':
22205796c8dcSSimon Schubert       ret = d_template_param (di);
22215796c8dcSSimon Schubert       if (d_peek_char (di) == 'I')
22225796c8dcSSimon Schubert 	{
22235796c8dcSSimon Schubert 	  /* This is <template-template-param> <template-args>.  The
22245796c8dcSSimon Schubert 	     <template-template-param> part is a substitution
22255796c8dcSSimon Schubert 	     candidate.  */
22265796c8dcSSimon Schubert 	  if (! d_add_substitution (di, ret))
22275796c8dcSSimon Schubert 	    return NULL;
22285796c8dcSSimon Schubert 	  ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
22295796c8dcSSimon Schubert 			     d_template_args (di));
22305796c8dcSSimon Schubert 	}
22315796c8dcSSimon Schubert       break;
22325796c8dcSSimon Schubert 
22335796c8dcSSimon Schubert     case 'S':
22345796c8dcSSimon Schubert       /* If this is a special substitution, then it is the start of
22355796c8dcSSimon Schubert 	 <class-enum-type>.  */
22365796c8dcSSimon Schubert       {
22375796c8dcSSimon Schubert 	char peek_next;
22385796c8dcSSimon Schubert 
22395796c8dcSSimon Schubert 	peek_next = d_peek_next_char (di);
22405796c8dcSSimon Schubert 	if (IS_DIGIT (peek_next)
22415796c8dcSSimon Schubert 	    || peek_next == '_'
22425796c8dcSSimon Schubert 	    || IS_UPPER (peek_next))
22435796c8dcSSimon Schubert 	  {
22445796c8dcSSimon Schubert 	    ret = d_substitution (di, 0);
22455796c8dcSSimon Schubert 	    /* The substituted name may have been a template name and
22465796c8dcSSimon Schubert 	       may be followed by tepmlate args.  */
22475796c8dcSSimon Schubert 	    if (d_peek_char (di) == 'I')
22485796c8dcSSimon Schubert 	      ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
22495796c8dcSSimon Schubert 				 d_template_args (di));
22505796c8dcSSimon Schubert 	    else
22515796c8dcSSimon Schubert 	      can_subst = 0;
22525796c8dcSSimon Schubert 	  }
22535796c8dcSSimon Schubert 	else
22545796c8dcSSimon Schubert 	  {
22555796c8dcSSimon Schubert 	    ret = d_class_enum_type (di);
22565796c8dcSSimon Schubert 	    /* If the substitution was a complete type, then it is not
22575796c8dcSSimon Schubert 	       a new substitution candidate.  However, if the
22585796c8dcSSimon Schubert 	       substitution was followed by template arguments, then
22595796c8dcSSimon Schubert 	       the whole thing is a substitution candidate.  */
22605796c8dcSSimon Schubert 	    if (ret != NULL && ret->type == DEMANGLE_COMPONENT_SUB_STD)
22615796c8dcSSimon Schubert 	      can_subst = 0;
22625796c8dcSSimon Schubert 	  }
22635796c8dcSSimon Schubert       }
22645796c8dcSSimon Schubert       break;
22655796c8dcSSimon Schubert 
22665796c8dcSSimon Schubert     case 'O':
22675796c8dcSSimon Schubert       d_advance (di, 1);
22685796c8dcSSimon Schubert       ret = d_make_comp (di, DEMANGLE_COMPONENT_RVALUE_REFERENCE,
22695796c8dcSSimon Schubert                          cplus_demangle_type (di), NULL);
22705796c8dcSSimon Schubert       break;
22715796c8dcSSimon Schubert 
22725796c8dcSSimon Schubert     case 'P':
22735796c8dcSSimon Schubert       d_advance (di, 1);
22745796c8dcSSimon Schubert       ret = d_make_comp (di, DEMANGLE_COMPONENT_POINTER,
22755796c8dcSSimon Schubert 			 cplus_demangle_type (di), NULL);
22765796c8dcSSimon Schubert       break;
22775796c8dcSSimon Schubert 
22785796c8dcSSimon Schubert     case 'R':
22795796c8dcSSimon Schubert       d_advance (di, 1);
22805796c8dcSSimon Schubert       ret = d_make_comp (di, DEMANGLE_COMPONENT_REFERENCE,
22815796c8dcSSimon Schubert                          cplus_demangle_type (di), NULL);
22825796c8dcSSimon Schubert       break;
22835796c8dcSSimon Schubert 
22845796c8dcSSimon Schubert     case 'C':
22855796c8dcSSimon Schubert       d_advance (di, 1);
22865796c8dcSSimon Schubert       ret = d_make_comp (di, DEMANGLE_COMPONENT_COMPLEX,
22875796c8dcSSimon Schubert 			 cplus_demangle_type (di), NULL);
22885796c8dcSSimon Schubert       break;
22895796c8dcSSimon Schubert 
22905796c8dcSSimon Schubert     case 'G':
22915796c8dcSSimon Schubert       d_advance (di, 1);
22925796c8dcSSimon Schubert       ret = d_make_comp (di, DEMANGLE_COMPONENT_IMAGINARY,
22935796c8dcSSimon Schubert 			 cplus_demangle_type (di), NULL);
22945796c8dcSSimon Schubert       break;
22955796c8dcSSimon Schubert 
22965796c8dcSSimon Schubert     case 'U':
22975796c8dcSSimon Schubert       d_advance (di, 1);
22985796c8dcSSimon Schubert       ret = d_source_name (di);
22995796c8dcSSimon Schubert       ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
23005796c8dcSSimon Schubert 			 cplus_demangle_type (di), ret);
23015796c8dcSSimon Schubert       break;
23025796c8dcSSimon Schubert 
23035796c8dcSSimon Schubert     case 'D':
23045796c8dcSSimon Schubert       can_subst = 0;
23055796c8dcSSimon Schubert       d_advance (di, 1);
23065796c8dcSSimon Schubert       peek = d_next_char (di);
23075796c8dcSSimon Schubert       switch (peek)
23085796c8dcSSimon Schubert 	{
23095796c8dcSSimon Schubert 	case 'T':
23105796c8dcSSimon Schubert 	case 't':
23115796c8dcSSimon Schubert 	  /* decltype (expression) */
23125796c8dcSSimon Schubert 	  ret = d_make_comp (di, DEMANGLE_COMPONENT_DECLTYPE,
23135796c8dcSSimon Schubert 			     d_expression (di), NULL);
23145796c8dcSSimon Schubert 	  if (ret && d_next_char (di) != 'E')
23155796c8dcSSimon Schubert 	    ret = NULL;
2316*ef5ccd6cSJohn Marino 	  can_subst = 1;
23175796c8dcSSimon Schubert 	  break;
23185796c8dcSSimon Schubert 
23195796c8dcSSimon Schubert 	case 'p':
23205796c8dcSSimon Schubert 	  /* Pack expansion.  */
23215796c8dcSSimon Schubert 	  ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
23225796c8dcSSimon Schubert 			     cplus_demangle_type (di), NULL);
2323*ef5ccd6cSJohn Marino 	  can_subst = 1;
2324*ef5ccd6cSJohn Marino 	  break;
2325*ef5ccd6cSJohn Marino 
2326*ef5ccd6cSJohn Marino 	case 'a':
2327*ef5ccd6cSJohn Marino 	  /* auto */
2328*ef5ccd6cSJohn Marino 	  ret = d_make_name (di, "auto", 4);
23295796c8dcSSimon Schubert 	  break;
23305796c8dcSSimon Schubert 
23315796c8dcSSimon Schubert 	case 'f':
23325796c8dcSSimon Schubert 	  /* 32-bit decimal floating point */
23335796c8dcSSimon Schubert 	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
23345796c8dcSSimon Schubert 	  di->expansion += ret->u.s_builtin.type->len;
23355796c8dcSSimon Schubert 	  break;
23365796c8dcSSimon Schubert 	case 'd':
23375796c8dcSSimon Schubert 	  /* 64-bit DFP */
23385796c8dcSSimon Schubert 	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[27]);
23395796c8dcSSimon Schubert 	  di->expansion += ret->u.s_builtin.type->len;
23405796c8dcSSimon Schubert 	  break;
23415796c8dcSSimon Schubert 	case 'e':
23425796c8dcSSimon Schubert 	  /* 128-bit DFP */
23435796c8dcSSimon Schubert 	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[28]);
23445796c8dcSSimon Schubert 	  di->expansion += ret->u.s_builtin.type->len;
23455796c8dcSSimon Schubert 	  break;
23465796c8dcSSimon Schubert 	case 'h':
23475796c8dcSSimon Schubert 	  /* 16-bit half-precision FP */
23485796c8dcSSimon Schubert 	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[29]);
23495796c8dcSSimon Schubert 	  di->expansion += ret->u.s_builtin.type->len;
23505796c8dcSSimon Schubert 	  break;
23515796c8dcSSimon Schubert 	case 's':
23525796c8dcSSimon Schubert 	  /* char16_t */
23535796c8dcSSimon Schubert 	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]);
23545796c8dcSSimon Schubert 	  di->expansion += ret->u.s_builtin.type->len;
23555796c8dcSSimon Schubert 	  break;
23565796c8dcSSimon Schubert 	case 'i':
23575796c8dcSSimon Schubert 	  /* char32_t */
23585796c8dcSSimon Schubert 	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
23595796c8dcSSimon Schubert 	  di->expansion += ret->u.s_builtin.type->len;
23605796c8dcSSimon Schubert 	  break;
23615796c8dcSSimon Schubert 
23625796c8dcSSimon Schubert 	case 'F':
23635796c8dcSSimon Schubert 	  /* Fixed point types. DF<int bits><length><fract bits><sat>  */
23645796c8dcSSimon Schubert 	  ret = d_make_empty (di);
23655796c8dcSSimon Schubert 	  ret->type = DEMANGLE_COMPONENT_FIXED_TYPE;
23665796c8dcSSimon Schubert 	  if ((ret->u.s_fixed.accum = IS_DIGIT (d_peek_char (di))))
23675796c8dcSSimon Schubert 	    /* For demangling we don't care about the bits.  */
23685796c8dcSSimon Schubert 	    d_number (di);
23695796c8dcSSimon Schubert 	  ret->u.s_fixed.length = cplus_demangle_type (di);
2370cf7f2e2dSJohn Marino 	  if (ret->u.s_fixed.length == NULL)
2371cf7f2e2dSJohn Marino 	    return NULL;
23725796c8dcSSimon Schubert 	  d_number (di);
23735796c8dcSSimon Schubert 	  peek = d_next_char (di);
23745796c8dcSSimon Schubert 	  ret->u.s_fixed.sat = (peek == 's');
23755796c8dcSSimon Schubert 	  break;
23765796c8dcSSimon Schubert 
2377cf7f2e2dSJohn Marino 	case 'v':
2378cf7f2e2dSJohn Marino 	  ret = d_vector_type (di);
2379*ef5ccd6cSJohn Marino 	  can_subst = 1;
2380cf7f2e2dSJohn Marino 	  break;
2381cf7f2e2dSJohn Marino 
2382cf7f2e2dSJohn Marino         case 'n':
2383cf7f2e2dSJohn Marino           /* decltype(nullptr) */
2384cf7f2e2dSJohn Marino 	  ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[32]);
2385cf7f2e2dSJohn Marino 	  di->expansion += ret->u.s_builtin.type->len;
2386cf7f2e2dSJohn Marino 	  break;
2387cf7f2e2dSJohn Marino 
23885796c8dcSSimon Schubert 	default:
23895796c8dcSSimon Schubert 	  return NULL;
23905796c8dcSSimon Schubert 	}
23915796c8dcSSimon Schubert       break;
23925796c8dcSSimon Schubert 
23935796c8dcSSimon Schubert     default:
23945796c8dcSSimon Schubert       return NULL;
23955796c8dcSSimon Schubert     }
23965796c8dcSSimon Schubert 
23975796c8dcSSimon Schubert   if (can_subst)
23985796c8dcSSimon Schubert     {
23995796c8dcSSimon Schubert       if (! d_add_substitution (di, ret))
24005796c8dcSSimon Schubert 	return NULL;
24015796c8dcSSimon Schubert     }
24025796c8dcSSimon Schubert 
24035796c8dcSSimon Schubert   return ret;
24045796c8dcSSimon Schubert }
24055796c8dcSSimon Schubert 
24065796c8dcSSimon Schubert /* <CV-qualifiers> ::= [r] [V] [K]  */
24075796c8dcSSimon Schubert 
24085796c8dcSSimon Schubert static struct demangle_component **
d_cv_qualifiers(struct d_info * di,struct demangle_component ** pret,int member_fn)24095796c8dcSSimon Schubert d_cv_qualifiers (struct d_info *di,
24105796c8dcSSimon Schubert                  struct demangle_component **pret, int member_fn)
24115796c8dcSSimon Schubert {
2412a45ae5f8SJohn Marino   struct demangle_component **pstart;
24135796c8dcSSimon Schubert   char peek;
24145796c8dcSSimon Schubert 
2415a45ae5f8SJohn Marino   pstart = pret;
24165796c8dcSSimon Schubert   peek = d_peek_char (di);
24175796c8dcSSimon Schubert   while (peek == 'r' || peek == 'V' || peek == 'K')
24185796c8dcSSimon Schubert     {
24195796c8dcSSimon Schubert       enum demangle_component_type t;
24205796c8dcSSimon Schubert 
24215796c8dcSSimon Schubert       d_advance (di, 1);
24225796c8dcSSimon Schubert       if (peek == 'r')
24235796c8dcSSimon Schubert 	{
24245796c8dcSSimon Schubert 	  t = (member_fn
24255796c8dcSSimon Schubert 	       ? DEMANGLE_COMPONENT_RESTRICT_THIS
24265796c8dcSSimon Schubert 	       : DEMANGLE_COMPONENT_RESTRICT);
24275796c8dcSSimon Schubert 	  di->expansion += sizeof "restrict";
24285796c8dcSSimon Schubert 	}
24295796c8dcSSimon Schubert       else if (peek == 'V')
24305796c8dcSSimon Schubert 	{
24315796c8dcSSimon Schubert 	  t = (member_fn
24325796c8dcSSimon Schubert 	       ? DEMANGLE_COMPONENT_VOLATILE_THIS
24335796c8dcSSimon Schubert 	       : DEMANGLE_COMPONENT_VOLATILE);
24345796c8dcSSimon Schubert 	  di->expansion += sizeof "volatile";
24355796c8dcSSimon Schubert 	}
24365796c8dcSSimon Schubert       else
24375796c8dcSSimon Schubert 	{
24385796c8dcSSimon Schubert 	  t = (member_fn
24395796c8dcSSimon Schubert 	       ? DEMANGLE_COMPONENT_CONST_THIS
24405796c8dcSSimon Schubert 	       : DEMANGLE_COMPONENT_CONST);
24415796c8dcSSimon Schubert 	  di->expansion += sizeof "const";
24425796c8dcSSimon Schubert 	}
24435796c8dcSSimon Schubert 
24445796c8dcSSimon Schubert       *pret = d_make_comp (di, t, NULL, NULL);
24455796c8dcSSimon Schubert       if (*pret == NULL)
24465796c8dcSSimon Schubert 	return NULL;
24475796c8dcSSimon Schubert       pret = &d_left (*pret);
24485796c8dcSSimon Schubert 
24495796c8dcSSimon Schubert       peek = d_peek_char (di);
24505796c8dcSSimon Schubert     }
24515796c8dcSSimon Schubert 
2452a45ae5f8SJohn Marino   if (!member_fn && peek == 'F')
2453a45ae5f8SJohn Marino     {
2454a45ae5f8SJohn Marino       while (pstart != pret)
2455a45ae5f8SJohn Marino 	{
2456a45ae5f8SJohn Marino 	  switch ((*pstart)->type)
2457a45ae5f8SJohn Marino 	    {
2458a45ae5f8SJohn Marino 	    case DEMANGLE_COMPONENT_RESTRICT:
2459a45ae5f8SJohn Marino 	      (*pstart)->type = DEMANGLE_COMPONENT_RESTRICT_THIS;
2460a45ae5f8SJohn Marino 	      break;
2461a45ae5f8SJohn Marino 	    case DEMANGLE_COMPONENT_VOLATILE:
2462a45ae5f8SJohn Marino 	      (*pstart)->type = DEMANGLE_COMPONENT_VOLATILE_THIS;
2463a45ae5f8SJohn Marino 	      break;
2464a45ae5f8SJohn Marino 	    case DEMANGLE_COMPONENT_CONST:
2465a45ae5f8SJohn Marino 	      (*pstart)->type = DEMANGLE_COMPONENT_CONST_THIS;
2466a45ae5f8SJohn Marino 	      break;
2467a45ae5f8SJohn Marino 	    default:
2468a45ae5f8SJohn Marino 	      break;
2469a45ae5f8SJohn Marino 	    }
2470a45ae5f8SJohn Marino 	  pstart = &d_left (*pstart);
2471a45ae5f8SJohn Marino 	}
2472a45ae5f8SJohn Marino     }
2473a45ae5f8SJohn Marino 
24745796c8dcSSimon Schubert   return pret;
24755796c8dcSSimon Schubert }
24765796c8dcSSimon Schubert 
24775796c8dcSSimon Schubert /* <function-type> ::= F [Y] <bare-function-type> E  */
24785796c8dcSSimon Schubert 
24795796c8dcSSimon Schubert static struct demangle_component *
d_function_type(struct d_info * di)24805796c8dcSSimon Schubert d_function_type (struct d_info *di)
24815796c8dcSSimon Schubert {
24825796c8dcSSimon Schubert   struct demangle_component *ret;
24835796c8dcSSimon Schubert 
24845796c8dcSSimon Schubert   if (! d_check_char (di, 'F'))
24855796c8dcSSimon Schubert     return NULL;
24865796c8dcSSimon Schubert   if (d_peek_char (di) == 'Y')
24875796c8dcSSimon Schubert     {
24885796c8dcSSimon Schubert       /* Function has C linkage.  We don't print this information.
24895796c8dcSSimon Schubert 	 FIXME: We should print it in verbose mode.  */
24905796c8dcSSimon Schubert       d_advance (di, 1);
24915796c8dcSSimon Schubert     }
24925796c8dcSSimon Schubert   ret = d_bare_function_type (di, 1);
24935796c8dcSSimon Schubert   if (! d_check_char (di, 'E'))
24945796c8dcSSimon Schubert     return NULL;
24955796c8dcSSimon Schubert   return ret;
24965796c8dcSSimon Schubert }
24975796c8dcSSimon Schubert 
2498cf7f2e2dSJohn Marino /* <type>+ */
24995796c8dcSSimon Schubert 
25005796c8dcSSimon Schubert static struct demangle_component *
d_parmlist(struct d_info * di)2501cf7f2e2dSJohn Marino d_parmlist (struct d_info *di)
25025796c8dcSSimon Schubert {
25035796c8dcSSimon Schubert   struct demangle_component *tl;
25045796c8dcSSimon Schubert   struct demangle_component **ptl;
25055796c8dcSSimon Schubert 
25065796c8dcSSimon Schubert   tl = NULL;
25075796c8dcSSimon Schubert   ptl = &tl;
25085796c8dcSSimon Schubert   while (1)
25095796c8dcSSimon Schubert     {
25105796c8dcSSimon Schubert       struct demangle_component *type;
25115796c8dcSSimon Schubert 
2512cf7f2e2dSJohn Marino       char peek = d_peek_char (di);
2513a45ae5f8SJohn Marino       if (peek == '\0' || peek == 'E' || peek == '.')
25145796c8dcSSimon Schubert 	break;
25155796c8dcSSimon Schubert       type = cplus_demangle_type (di);
25165796c8dcSSimon Schubert       if (type == NULL)
25175796c8dcSSimon Schubert 	return NULL;
25185796c8dcSSimon Schubert       *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL);
25195796c8dcSSimon Schubert       if (*ptl == NULL)
25205796c8dcSSimon Schubert 	return NULL;
25215796c8dcSSimon Schubert       ptl = &d_right (*ptl);
25225796c8dcSSimon Schubert     }
25235796c8dcSSimon Schubert 
25245796c8dcSSimon Schubert   /* There should be at least one parameter type besides the optional
25255796c8dcSSimon Schubert      return type.  A function which takes no arguments will have a
25265796c8dcSSimon Schubert      single parameter type void.  */
25275796c8dcSSimon Schubert   if (tl == NULL)
25285796c8dcSSimon Schubert     return NULL;
25295796c8dcSSimon Schubert 
25305796c8dcSSimon Schubert   /* If we have a single parameter type void, omit it.  */
25315796c8dcSSimon Schubert   if (d_right (tl) == NULL
25325796c8dcSSimon Schubert       && d_left (tl)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
25335796c8dcSSimon Schubert       && d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID)
25345796c8dcSSimon Schubert     {
25355796c8dcSSimon Schubert       di->expansion -= d_left (tl)->u.s_builtin.type->len;
2536cf7f2e2dSJohn Marino       d_left (tl) = NULL;
25375796c8dcSSimon Schubert     }
25385796c8dcSSimon Schubert 
2539cf7f2e2dSJohn Marino   return tl;
2540cf7f2e2dSJohn Marino }
2541cf7f2e2dSJohn Marino 
2542cf7f2e2dSJohn Marino /* <bare-function-type> ::= [J]<type>+  */
2543cf7f2e2dSJohn Marino 
2544cf7f2e2dSJohn Marino static struct demangle_component *
d_bare_function_type(struct d_info * di,int has_return_type)2545cf7f2e2dSJohn Marino d_bare_function_type (struct d_info *di, int has_return_type)
2546cf7f2e2dSJohn Marino {
2547cf7f2e2dSJohn Marino   struct demangle_component *return_type;
2548cf7f2e2dSJohn Marino   struct demangle_component *tl;
2549cf7f2e2dSJohn Marino   char peek;
2550cf7f2e2dSJohn Marino 
2551cf7f2e2dSJohn Marino   /* Detect special qualifier indicating that the first argument
2552cf7f2e2dSJohn Marino      is the return type.  */
2553cf7f2e2dSJohn Marino   peek = d_peek_char (di);
2554cf7f2e2dSJohn Marino   if (peek == 'J')
2555cf7f2e2dSJohn Marino     {
2556cf7f2e2dSJohn Marino       d_advance (di, 1);
2557cf7f2e2dSJohn Marino       has_return_type = 1;
2558cf7f2e2dSJohn Marino     }
2559cf7f2e2dSJohn Marino 
2560cf7f2e2dSJohn Marino   if (has_return_type)
2561cf7f2e2dSJohn Marino     {
2562cf7f2e2dSJohn Marino       return_type = cplus_demangle_type (di);
2563cf7f2e2dSJohn Marino       if (return_type == NULL)
2564cf7f2e2dSJohn Marino 	return NULL;
2565cf7f2e2dSJohn Marino     }
2566cf7f2e2dSJohn Marino   else
2567cf7f2e2dSJohn Marino     return_type = NULL;
2568cf7f2e2dSJohn Marino 
2569cf7f2e2dSJohn Marino   tl = d_parmlist (di);
2570cf7f2e2dSJohn Marino   if (tl == NULL)
2571cf7f2e2dSJohn Marino     return NULL;
2572cf7f2e2dSJohn Marino 
2573cf7f2e2dSJohn Marino   return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE,
2574cf7f2e2dSJohn Marino 		      return_type, tl);
25755796c8dcSSimon Schubert }
25765796c8dcSSimon Schubert 
25775796c8dcSSimon Schubert /* <class-enum-type> ::= <name>  */
25785796c8dcSSimon Schubert 
25795796c8dcSSimon Schubert static struct demangle_component *
d_class_enum_type(struct d_info * di)25805796c8dcSSimon Schubert d_class_enum_type (struct d_info *di)
25815796c8dcSSimon Schubert {
25825796c8dcSSimon Schubert   return d_name (di);
25835796c8dcSSimon Schubert }
25845796c8dcSSimon Schubert 
25855796c8dcSSimon Schubert /* <array-type> ::= A <(positive dimension) number> _ <(element) type>
25865796c8dcSSimon Schubert                 ::= A [<(dimension) expression>] _ <(element) type>
25875796c8dcSSimon Schubert */
25885796c8dcSSimon Schubert 
25895796c8dcSSimon Schubert static struct demangle_component *
d_array_type(struct d_info * di)25905796c8dcSSimon Schubert d_array_type (struct d_info *di)
25915796c8dcSSimon Schubert {
25925796c8dcSSimon Schubert   char peek;
25935796c8dcSSimon Schubert   struct demangle_component *dim;
25945796c8dcSSimon Schubert 
25955796c8dcSSimon Schubert   if (! d_check_char (di, 'A'))
25965796c8dcSSimon Schubert     return NULL;
25975796c8dcSSimon Schubert 
25985796c8dcSSimon Schubert   peek = d_peek_char (di);
25995796c8dcSSimon Schubert   if (peek == '_')
26005796c8dcSSimon Schubert     dim = NULL;
26015796c8dcSSimon Schubert   else if (IS_DIGIT (peek))
26025796c8dcSSimon Schubert     {
26035796c8dcSSimon Schubert       const char *s;
26045796c8dcSSimon Schubert 
26055796c8dcSSimon Schubert       s = d_str (di);
26065796c8dcSSimon Schubert       do
26075796c8dcSSimon Schubert 	{
26085796c8dcSSimon Schubert 	  d_advance (di, 1);
26095796c8dcSSimon Schubert 	  peek = d_peek_char (di);
26105796c8dcSSimon Schubert 	}
26115796c8dcSSimon Schubert       while (IS_DIGIT (peek));
26125796c8dcSSimon Schubert       dim = d_make_name (di, s, d_str (di) - s);
26135796c8dcSSimon Schubert       if (dim == NULL)
26145796c8dcSSimon Schubert 	return NULL;
26155796c8dcSSimon Schubert     }
26165796c8dcSSimon Schubert   else
26175796c8dcSSimon Schubert     {
26185796c8dcSSimon Schubert       dim = d_expression (di);
26195796c8dcSSimon Schubert       if (dim == NULL)
26205796c8dcSSimon Schubert 	return NULL;
26215796c8dcSSimon Schubert     }
26225796c8dcSSimon Schubert 
26235796c8dcSSimon Schubert   if (! d_check_char (di, '_'))
26245796c8dcSSimon Schubert     return NULL;
26255796c8dcSSimon Schubert 
26265796c8dcSSimon Schubert   return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim,
26275796c8dcSSimon Schubert 		      cplus_demangle_type (di));
26285796c8dcSSimon Schubert }
26295796c8dcSSimon Schubert 
2630cf7f2e2dSJohn Marino /* <vector-type> ::= Dv <number> _ <type>
2631cf7f2e2dSJohn Marino                  ::= Dv _ <expression> _ <type> */
2632cf7f2e2dSJohn Marino 
2633cf7f2e2dSJohn Marino static struct demangle_component *
d_vector_type(struct d_info * di)2634cf7f2e2dSJohn Marino d_vector_type (struct d_info *di)
2635cf7f2e2dSJohn Marino {
2636cf7f2e2dSJohn Marino   char peek;
2637cf7f2e2dSJohn Marino   struct demangle_component *dim;
2638cf7f2e2dSJohn Marino 
2639cf7f2e2dSJohn Marino   peek = d_peek_char (di);
2640cf7f2e2dSJohn Marino   if (peek == '_')
2641cf7f2e2dSJohn Marino     {
2642cf7f2e2dSJohn Marino       d_advance (di, 1);
2643cf7f2e2dSJohn Marino       dim = d_expression (di);
2644cf7f2e2dSJohn Marino     }
2645cf7f2e2dSJohn Marino   else
2646cf7f2e2dSJohn Marino     dim = d_number_component (di);
2647cf7f2e2dSJohn Marino 
2648cf7f2e2dSJohn Marino   if (dim == NULL)
2649cf7f2e2dSJohn Marino     return NULL;
2650cf7f2e2dSJohn Marino 
2651cf7f2e2dSJohn Marino   if (! d_check_char (di, '_'))
2652cf7f2e2dSJohn Marino     return NULL;
2653cf7f2e2dSJohn Marino 
2654cf7f2e2dSJohn Marino   return d_make_comp (di, DEMANGLE_COMPONENT_VECTOR_TYPE, dim,
2655cf7f2e2dSJohn Marino 		      cplus_demangle_type (di));
2656cf7f2e2dSJohn Marino }
2657cf7f2e2dSJohn Marino 
26585796c8dcSSimon Schubert /* <pointer-to-member-type> ::= M <(class) type> <(member) type>  */
26595796c8dcSSimon Schubert 
26605796c8dcSSimon Schubert static struct demangle_component *
d_pointer_to_member_type(struct d_info * di)26615796c8dcSSimon Schubert d_pointer_to_member_type (struct d_info *di)
26625796c8dcSSimon Schubert {
26635796c8dcSSimon Schubert   struct demangle_component *cl;
26645796c8dcSSimon Schubert   struct demangle_component *mem;
26655796c8dcSSimon Schubert   struct demangle_component **pmem;
26665796c8dcSSimon Schubert 
26675796c8dcSSimon Schubert   if (! d_check_char (di, 'M'))
26685796c8dcSSimon Schubert     return NULL;
26695796c8dcSSimon Schubert 
26705796c8dcSSimon Schubert   cl = cplus_demangle_type (di);
26715796c8dcSSimon Schubert 
26725796c8dcSSimon Schubert   /* The ABI specifies that any type can be a substitution source, and
26735796c8dcSSimon Schubert      that M is followed by two types, and that when a CV-qualified
26745796c8dcSSimon Schubert      type is seen both the base type and the CV-qualified types are
26755796c8dcSSimon Schubert      substitution sources.  The ABI also specifies that for a pointer
26765796c8dcSSimon Schubert      to a CV-qualified member function, the qualifiers are attached to
26775796c8dcSSimon Schubert      the second type.  Given the grammar, a plain reading of the ABI
26785796c8dcSSimon Schubert      suggests that both the CV-qualified member function and the
26795796c8dcSSimon Schubert      non-qualified member function are substitution sources.  However,
26805796c8dcSSimon Schubert      g++ does not work that way.  g++ treats only the CV-qualified
26815796c8dcSSimon Schubert      member function as a substitution source.  FIXME.  So to work
26825796c8dcSSimon Schubert      with g++, we need to pull off the CV-qualifiers here, in order to
26835796c8dcSSimon Schubert      avoid calling add_substitution() in cplus_demangle_type().  But
26845796c8dcSSimon Schubert      for a CV-qualified member which is not a function, g++ does
26855796c8dcSSimon Schubert      follow the ABI, so we need to handle that case here by calling
26865796c8dcSSimon Schubert      d_add_substitution ourselves.  */
26875796c8dcSSimon Schubert 
26885796c8dcSSimon Schubert   pmem = d_cv_qualifiers (di, &mem, 1);
26895796c8dcSSimon Schubert   if (pmem == NULL)
26905796c8dcSSimon Schubert     return NULL;
26915796c8dcSSimon Schubert   *pmem = cplus_demangle_type (di);
26925796c8dcSSimon Schubert   if (*pmem == NULL)
26935796c8dcSSimon Schubert     return NULL;
26945796c8dcSSimon Schubert 
26955796c8dcSSimon Schubert   if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
26965796c8dcSSimon Schubert     {
26975796c8dcSSimon Schubert       if (! d_add_substitution (di, mem))
26985796c8dcSSimon Schubert 	return NULL;
26995796c8dcSSimon Schubert     }
27005796c8dcSSimon Schubert 
27015796c8dcSSimon Schubert   return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
27025796c8dcSSimon Schubert }
27035796c8dcSSimon Schubert 
2704cf7f2e2dSJohn Marino /* <non-negative number> _ */
2705cf7f2e2dSJohn Marino 
2706cf7f2e2dSJohn Marino static long
d_compact_number(struct d_info * di)2707cf7f2e2dSJohn Marino d_compact_number (struct d_info *di)
2708cf7f2e2dSJohn Marino {
2709cf7f2e2dSJohn Marino   long num;
2710cf7f2e2dSJohn Marino   if (d_peek_char (di) == '_')
2711cf7f2e2dSJohn Marino     num = 0;
2712cf7f2e2dSJohn Marino   else if (d_peek_char (di) == 'n')
2713cf7f2e2dSJohn Marino     return -1;
2714cf7f2e2dSJohn Marino   else
2715cf7f2e2dSJohn Marino     num = d_number (di) + 1;
2716cf7f2e2dSJohn Marino 
2717cf7f2e2dSJohn Marino   if (! d_check_char (di, '_'))
2718cf7f2e2dSJohn Marino     return -1;
2719cf7f2e2dSJohn Marino   return num;
2720cf7f2e2dSJohn Marino }
2721cf7f2e2dSJohn Marino 
27225796c8dcSSimon Schubert /* <template-param> ::= T_
27235796c8dcSSimon Schubert                     ::= T <(parameter-2 non-negative) number> _
27245796c8dcSSimon Schubert */
27255796c8dcSSimon Schubert 
27265796c8dcSSimon Schubert static struct demangle_component *
d_template_param(struct d_info * di)27275796c8dcSSimon Schubert d_template_param (struct d_info *di)
27285796c8dcSSimon Schubert {
27295796c8dcSSimon Schubert   long param;
27305796c8dcSSimon Schubert 
27315796c8dcSSimon Schubert   if (! d_check_char (di, 'T'))
27325796c8dcSSimon Schubert     return NULL;
27335796c8dcSSimon Schubert 
2734cf7f2e2dSJohn Marino   param = d_compact_number (di);
27355796c8dcSSimon Schubert   if (param < 0)
27365796c8dcSSimon Schubert     return NULL;
27375796c8dcSSimon Schubert 
27385796c8dcSSimon Schubert   ++di->did_subs;
27395796c8dcSSimon Schubert 
27405796c8dcSSimon Schubert   return d_make_template_param (di, param);
27415796c8dcSSimon Schubert }
27425796c8dcSSimon Schubert 
27435796c8dcSSimon Schubert /* <template-args> ::= I <template-arg>+ E  */
27445796c8dcSSimon Schubert 
27455796c8dcSSimon Schubert static struct demangle_component *
d_template_args(struct d_info * di)27465796c8dcSSimon Schubert d_template_args (struct d_info *di)
27475796c8dcSSimon Schubert {
27485796c8dcSSimon Schubert   struct demangle_component *hold_last_name;
27495796c8dcSSimon Schubert   struct demangle_component *al;
27505796c8dcSSimon Schubert   struct demangle_component **pal;
27515796c8dcSSimon Schubert 
27525796c8dcSSimon Schubert   /* Preserve the last name we saw--don't let the template arguments
27535796c8dcSSimon Schubert      clobber it, as that would give us the wrong name for a subsequent
27545796c8dcSSimon Schubert      constructor or destructor.  */
27555796c8dcSSimon Schubert   hold_last_name = di->last_name;
27565796c8dcSSimon Schubert 
2757*ef5ccd6cSJohn Marino   if (d_peek_char (di) != 'I'
2758*ef5ccd6cSJohn Marino       && d_peek_char (di) != 'J')
27595796c8dcSSimon Schubert     return NULL;
2760*ef5ccd6cSJohn Marino   d_advance (di, 1);
27615796c8dcSSimon Schubert 
27625796c8dcSSimon Schubert   if (d_peek_char (di) == 'E')
27635796c8dcSSimon Schubert     {
27645796c8dcSSimon Schubert       /* An argument pack can be empty.  */
27655796c8dcSSimon Schubert       d_advance (di, 1);
27665796c8dcSSimon Schubert       return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, NULL, NULL);
27675796c8dcSSimon Schubert     }
27685796c8dcSSimon Schubert 
27695796c8dcSSimon Schubert   al = NULL;
27705796c8dcSSimon Schubert   pal = &al;
27715796c8dcSSimon Schubert   while (1)
27725796c8dcSSimon Schubert     {
27735796c8dcSSimon Schubert       struct demangle_component *a;
27745796c8dcSSimon Schubert 
27755796c8dcSSimon Schubert       a = d_template_arg (di);
27765796c8dcSSimon Schubert       if (a == NULL)
27775796c8dcSSimon Schubert 	return NULL;
27785796c8dcSSimon Schubert 
27795796c8dcSSimon Schubert       *pal = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, a, NULL);
27805796c8dcSSimon Schubert       if (*pal == NULL)
27815796c8dcSSimon Schubert 	return NULL;
27825796c8dcSSimon Schubert       pal = &d_right (*pal);
27835796c8dcSSimon Schubert 
27845796c8dcSSimon Schubert       if (d_peek_char (di) == 'E')
27855796c8dcSSimon Schubert 	{
27865796c8dcSSimon Schubert 	  d_advance (di, 1);
27875796c8dcSSimon Schubert 	  break;
27885796c8dcSSimon Schubert 	}
27895796c8dcSSimon Schubert     }
27905796c8dcSSimon Schubert 
27915796c8dcSSimon Schubert   di->last_name = hold_last_name;
27925796c8dcSSimon Schubert 
27935796c8dcSSimon Schubert   return al;
27945796c8dcSSimon Schubert }
27955796c8dcSSimon Schubert 
27965796c8dcSSimon Schubert /* <template-arg> ::= <type>
27975796c8dcSSimon Schubert                   ::= X <expression> E
27985796c8dcSSimon Schubert                   ::= <expr-primary>
27995796c8dcSSimon Schubert */
28005796c8dcSSimon Schubert 
28015796c8dcSSimon Schubert static struct demangle_component *
d_template_arg(struct d_info * di)28025796c8dcSSimon Schubert d_template_arg (struct d_info *di)
28035796c8dcSSimon Schubert {
28045796c8dcSSimon Schubert   struct demangle_component *ret;
28055796c8dcSSimon Schubert 
28065796c8dcSSimon Schubert   switch (d_peek_char (di))
28075796c8dcSSimon Schubert     {
28085796c8dcSSimon Schubert     case 'X':
28095796c8dcSSimon Schubert       d_advance (di, 1);
28105796c8dcSSimon Schubert       ret = d_expression (di);
28115796c8dcSSimon Schubert       if (! d_check_char (di, 'E'))
28125796c8dcSSimon Schubert 	return NULL;
28135796c8dcSSimon Schubert       return ret;
28145796c8dcSSimon Schubert 
28155796c8dcSSimon Schubert     case 'L':
28165796c8dcSSimon Schubert       return d_expr_primary (di);
28175796c8dcSSimon Schubert 
28185796c8dcSSimon Schubert     case 'I':
2819*ef5ccd6cSJohn Marino     case 'J':
28205796c8dcSSimon Schubert       /* An argument pack.  */
28215796c8dcSSimon Schubert       return d_template_args (di);
28225796c8dcSSimon Schubert 
28235796c8dcSSimon Schubert     default:
28245796c8dcSSimon Schubert       return cplus_demangle_type (di);
28255796c8dcSSimon Schubert     }
28265796c8dcSSimon Schubert }
28275796c8dcSSimon Schubert 
2828*ef5ccd6cSJohn Marino /* Parse a sequence of expressions until we hit the terminator
2829*ef5ccd6cSJohn Marino    character.  */
28305796c8dcSSimon Schubert 
28315796c8dcSSimon Schubert static struct demangle_component *
d_exprlist(struct d_info * di,char terminator)2832*ef5ccd6cSJohn Marino d_exprlist (struct d_info *di, char terminator)
28335796c8dcSSimon Schubert {
28345796c8dcSSimon Schubert   struct demangle_component *list = NULL;
28355796c8dcSSimon Schubert   struct demangle_component **p = &list;
28365796c8dcSSimon Schubert 
2837*ef5ccd6cSJohn Marino   if (d_peek_char (di) == terminator)
28385796c8dcSSimon Schubert     {
28395796c8dcSSimon Schubert       d_advance (di, 1);
28405796c8dcSSimon Schubert       return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL);
28415796c8dcSSimon Schubert     }
28425796c8dcSSimon Schubert 
28435796c8dcSSimon Schubert   while (1)
28445796c8dcSSimon Schubert     {
28455796c8dcSSimon Schubert       struct demangle_component *arg = d_expression (di);
28465796c8dcSSimon Schubert       if (arg == NULL)
28475796c8dcSSimon Schubert 	return NULL;
28485796c8dcSSimon Schubert 
28495796c8dcSSimon Schubert       *p = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, arg, NULL);
28505796c8dcSSimon Schubert       if (*p == NULL)
28515796c8dcSSimon Schubert 	return NULL;
28525796c8dcSSimon Schubert       p = &d_right (*p);
28535796c8dcSSimon Schubert 
2854*ef5ccd6cSJohn Marino       if (d_peek_char (di) == terminator)
28555796c8dcSSimon Schubert 	{
28565796c8dcSSimon Schubert 	  d_advance (di, 1);
28575796c8dcSSimon Schubert 	  break;
28585796c8dcSSimon Schubert 	}
28595796c8dcSSimon Schubert     }
28605796c8dcSSimon Schubert 
28615796c8dcSSimon Schubert   return list;
28625796c8dcSSimon Schubert }
28635796c8dcSSimon Schubert 
2864*ef5ccd6cSJohn Marino /* Returns nonzero iff OP is an operator for a C++ cast: const_cast,
2865*ef5ccd6cSJohn Marino    dynamic_cast, static_cast or reinterpret_cast.  */
2866*ef5ccd6cSJohn Marino 
2867*ef5ccd6cSJohn Marino static int
op_is_new_cast(struct demangle_component * op)2868*ef5ccd6cSJohn Marino op_is_new_cast (struct demangle_component *op)
2869*ef5ccd6cSJohn Marino {
2870*ef5ccd6cSJohn Marino   const char *code = op->u.s_operator.op->code;
2871*ef5ccd6cSJohn Marino   return (code[1] == 'c'
2872*ef5ccd6cSJohn Marino 	  && (code[0] == 's' || code[0] == 'd'
2873*ef5ccd6cSJohn Marino 	      || code[0] == 'c' || code[0] == 'r'));
2874*ef5ccd6cSJohn Marino }
2875*ef5ccd6cSJohn Marino 
28765796c8dcSSimon Schubert /* <expression> ::= <(unary) operator-name> <expression>
28775796c8dcSSimon Schubert                 ::= <(binary) operator-name> <expression> <expression>
28785796c8dcSSimon Schubert                 ::= <(trinary) operator-name> <expression> <expression> <expression>
28795796c8dcSSimon Schubert 		::= cl <expression>+ E
28805796c8dcSSimon Schubert                 ::= st <type>
28815796c8dcSSimon Schubert                 ::= <template-param>
28825796c8dcSSimon Schubert                 ::= sr <type> <unqualified-name>
28835796c8dcSSimon Schubert                 ::= sr <type> <unqualified-name> <template-args>
28845796c8dcSSimon Schubert                 ::= <expr-primary>
28855796c8dcSSimon Schubert */
28865796c8dcSSimon Schubert 
28875796c8dcSSimon Schubert static struct demangle_component *
d_expression(struct d_info * di)28885796c8dcSSimon Schubert d_expression (struct d_info *di)
28895796c8dcSSimon Schubert {
28905796c8dcSSimon Schubert   char peek;
28915796c8dcSSimon Schubert 
28925796c8dcSSimon Schubert   peek = d_peek_char (di);
28935796c8dcSSimon Schubert   if (peek == 'L')
28945796c8dcSSimon Schubert     return d_expr_primary (di);
28955796c8dcSSimon Schubert   else if (peek == 'T')
28965796c8dcSSimon Schubert     return d_template_param (di);
28975796c8dcSSimon Schubert   else if (peek == 's' && d_peek_next_char (di) == 'r')
28985796c8dcSSimon Schubert     {
28995796c8dcSSimon Schubert       struct demangle_component *type;
29005796c8dcSSimon Schubert       struct demangle_component *name;
29015796c8dcSSimon Schubert 
29025796c8dcSSimon Schubert       d_advance (di, 2);
29035796c8dcSSimon Schubert       type = cplus_demangle_type (di);
29045796c8dcSSimon Schubert       name = d_unqualified_name (di);
29055796c8dcSSimon Schubert       if (d_peek_char (di) != 'I')
29065796c8dcSSimon Schubert 	return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name);
29075796c8dcSSimon Schubert       else
29085796c8dcSSimon Schubert 	return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type,
29095796c8dcSSimon Schubert 			    d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
29105796c8dcSSimon Schubert 					 d_template_args (di)));
29115796c8dcSSimon Schubert     }
29125796c8dcSSimon Schubert   else if (peek == 's' && d_peek_next_char (di) == 'p')
29135796c8dcSSimon Schubert     {
29145796c8dcSSimon Schubert       d_advance (di, 2);
29155796c8dcSSimon Schubert       return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
29165796c8dcSSimon Schubert 			  d_expression (di), NULL);
29175796c8dcSSimon Schubert     }
29185796c8dcSSimon Schubert   else if (peek == 'f' && d_peek_next_char (di) == 'p')
29195796c8dcSSimon Schubert     {
29205796c8dcSSimon Schubert       /* Function parameter used in a late-specified return type.  */
29215796c8dcSSimon Schubert       int index;
29225796c8dcSSimon Schubert       d_advance (di, 2);
2923a45ae5f8SJohn Marino       if (d_peek_char (di) == 'T')
2924a45ae5f8SJohn Marino 	{
2925a45ae5f8SJohn Marino 	  /* 'this' parameter.  */
2926a45ae5f8SJohn Marino 	  d_advance (di, 1);
2927a45ae5f8SJohn Marino 	  index = 0;
2928a45ae5f8SJohn Marino 	}
2929a45ae5f8SJohn Marino       else
2930a45ae5f8SJohn Marino 	{
2931a45ae5f8SJohn Marino 	  index = d_compact_number (di) + 1;
2932a45ae5f8SJohn Marino 	  if (index == 0)
29335796c8dcSSimon Schubert 	    return NULL;
2934a45ae5f8SJohn Marino 	}
29355796c8dcSSimon Schubert       return d_make_function_param (di, index);
29365796c8dcSSimon Schubert     }
2937cf7f2e2dSJohn Marino   else if (IS_DIGIT (peek)
2938cf7f2e2dSJohn Marino 	   || (peek == 'o' && d_peek_next_char (di) == 'n'))
29395796c8dcSSimon Schubert     {
29405796c8dcSSimon Schubert       /* We can get an unqualified name as an expression in the case of
2941cf7f2e2dSJohn Marino          a dependent function call, i.e. decltype(f(t)).  */
2942cf7f2e2dSJohn Marino       struct demangle_component *name;
2943cf7f2e2dSJohn Marino 
2944cf7f2e2dSJohn Marino       if (peek == 'o')
2945cf7f2e2dSJohn Marino 	/* operator-function-id, i.e. operator+(t).  */
2946cf7f2e2dSJohn Marino 	d_advance (di, 2);
2947cf7f2e2dSJohn Marino 
2948cf7f2e2dSJohn Marino       name = d_unqualified_name (di);
29495796c8dcSSimon Schubert       if (name == NULL)
29505796c8dcSSimon Schubert 	return NULL;
29515796c8dcSSimon Schubert       if (d_peek_char (di) == 'I')
29525796c8dcSSimon Schubert 	return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
29535796c8dcSSimon Schubert 			    d_template_args (di));
29545796c8dcSSimon Schubert       else
29555796c8dcSSimon Schubert 	return name;
29565796c8dcSSimon Schubert     }
2957*ef5ccd6cSJohn Marino   else if ((peek == 'i' || peek == 't')
2958*ef5ccd6cSJohn Marino 	   && d_peek_next_char (di) == 'l')
2959*ef5ccd6cSJohn Marino     {
2960*ef5ccd6cSJohn Marino       /* Brace-enclosed initializer list, untyped or typed.  */
2961*ef5ccd6cSJohn Marino       struct demangle_component *type = NULL;
2962*ef5ccd6cSJohn Marino       if (peek == 't')
2963*ef5ccd6cSJohn Marino 	type = cplus_demangle_type (di);
2964*ef5ccd6cSJohn Marino       d_advance (di, 2);
2965*ef5ccd6cSJohn Marino       return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
2966*ef5ccd6cSJohn Marino 			  type, d_exprlist (di, 'E'));
2967*ef5ccd6cSJohn Marino     }
29685796c8dcSSimon Schubert   else
29695796c8dcSSimon Schubert     {
29705796c8dcSSimon Schubert       struct demangle_component *op;
2971*ef5ccd6cSJohn Marino       const char *code = NULL;
29725796c8dcSSimon Schubert       int args;
29735796c8dcSSimon Schubert 
29745796c8dcSSimon Schubert       op = d_operator_name (di);
29755796c8dcSSimon Schubert       if (op == NULL)
29765796c8dcSSimon Schubert 	return NULL;
29775796c8dcSSimon Schubert 
29785796c8dcSSimon Schubert       if (op->type == DEMANGLE_COMPONENT_OPERATOR)
2979*ef5ccd6cSJohn Marino 	{
2980*ef5ccd6cSJohn Marino 	  code = op->u.s_operator.op->code;
29815796c8dcSSimon Schubert 	  di->expansion += op->u.s_operator.op->len - 2;
2982*ef5ccd6cSJohn Marino 	  if (strcmp (code, "st") == 0)
29835796c8dcSSimon Schubert 	    return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
29845796c8dcSSimon Schubert 				cplus_demangle_type (di));
2985*ef5ccd6cSJohn Marino 	}
29865796c8dcSSimon Schubert 
29875796c8dcSSimon Schubert       switch (op->type)
29885796c8dcSSimon Schubert 	{
29895796c8dcSSimon Schubert 	default:
29905796c8dcSSimon Schubert 	  return NULL;
29915796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_OPERATOR:
29925796c8dcSSimon Schubert 	  args = op->u.s_operator.op->args;
29935796c8dcSSimon Schubert 	  break;
29945796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
29955796c8dcSSimon Schubert 	  args = op->u.s_extended_operator.args;
29965796c8dcSSimon Schubert 	  break;
29975796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_CAST:
29985796c8dcSSimon Schubert 	  args = 1;
29995796c8dcSSimon Schubert 	  break;
30005796c8dcSSimon Schubert 	}
30015796c8dcSSimon Schubert 
30025796c8dcSSimon Schubert       switch (args)
30035796c8dcSSimon Schubert 	{
3004*ef5ccd6cSJohn Marino 	case 0:
3005*ef5ccd6cSJohn Marino 	  return d_make_comp (di, DEMANGLE_COMPONENT_NULLARY, op, NULL);
3006*ef5ccd6cSJohn Marino 
30075796c8dcSSimon Schubert 	case 1:
30085796c8dcSSimon Schubert 	  {
30095796c8dcSSimon Schubert 	    struct demangle_component *operand;
3010*ef5ccd6cSJohn Marino 	    int suffix = 0;
3011*ef5ccd6cSJohn Marino 
3012*ef5ccd6cSJohn Marino 	    if (code && (code[0] == 'p' || code[0] == 'm')
3013*ef5ccd6cSJohn Marino 		&& code[1] == code[0])
3014*ef5ccd6cSJohn Marino 	      /* pp_ and mm_ are the prefix variants.  */
3015*ef5ccd6cSJohn Marino 	      suffix = !d_check_char (di, '_');
3016*ef5ccd6cSJohn Marino 
30175796c8dcSSimon Schubert 	    if (op->type == DEMANGLE_COMPONENT_CAST
30185796c8dcSSimon Schubert 		&& d_check_char (di, '_'))
3019*ef5ccd6cSJohn Marino 	      operand = d_exprlist (di, 'E');
30205796c8dcSSimon Schubert 	    else
30215796c8dcSSimon Schubert 	      operand = d_expression (di);
3022*ef5ccd6cSJohn Marino 
3023*ef5ccd6cSJohn Marino 	    if (suffix)
3024*ef5ccd6cSJohn Marino 	      /* Indicate the suffix variant for d_print_comp.  */
3025*ef5ccd6cSJohn Marino 	      return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
3026*ef5ccd6cSJohn Marino 				  d_make_comp (di,
3027*ef5ccd6cSJohn Marino 					       DEMANGLE_COMPONENT_BINARY_ARGS,
3028*ef5ccd6cSJohn Marino 					       operand, operand));
3029*ef5ccd6cSJohn Marino 	    else
30305796c8dcSSimon Schubert 	      return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
30315796c8dcSSimon Schubert 				  operand);
30325796c8dcSSimon Schubert 	  }
30335796c8dcSSimon Schubert 	case 2:
30345796c8dcSSimon Schubert 	  {
30355796c8dcSSimon Schubert 	    struct demangle_component *left;
30365796c8dcSSimon Schubert 	    struct demangle_component *right;
30375796c8dcSSimon Schubert 
3038*ef5ccd6cSJohn Marino 	    if (op_is_new_cast (op))
3039*ef5ccd6cSJohn Marino 	      left = cplus_demangle_type (di);
3040*ef5ccd6cSJohn Marino 	    else
30415796c8dcSSimon Schubert 	      left = d_expression (di);
3042cf7f2e2dSJohn Marino 	    if (!strcmp (code, "cl"))
3043*ef5ccd6cSJohn Marino 	      right = d_exprlist (di, 'E');
3044cf7f2e2dSJohn Marino 	    else if (!strcmp (code, "dt") || !strcmp (code, "pt"))
3045cf7f2e2dSJohn Marino 	      {
3046cf7f2e2dSJohn Marino 		right = d_unqualified_name (di);
3047cf7f2e2dSJohn Marino 		if (d_peek_char (di) == 'I')
3048cf7f2e2dSJohn Marino 		  right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE,
3049cf7f2e2dSJohn Marino 				       right, d_template_args (di));
3050cf7f2e2dSJohn Marino 	      }
30515796c8dcSSimon Schubert 	    else
30525796c8dcSSimon Schubert 	      right = d_expression (di);
30535796c8dcSSimon Schubert 
30545796c8dcSSimon Schubert 	    return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op,
30555796c8dcSSimon Schubert 				d_make_comp (di,
30565796c8dcSSimon Schubert 					     DEMANGLE_COMPONENT_BINARY_ARGS,
30575796c8dcSSimon Schubert 					     left, right));
30585796c8dcSSimon Schubert 	  }
30595796c8dcSSimon Schubert 	case 3:
30605796c8dcSSimon Schubert 	  {
30615796c8dcSSimon Schubert 	    struct demangle_component *first;
30625796c8dcSSimon Schubert 	    struct demangle_component *second;
3063*ef5ccd6cSJohn Marino 	    struct demangle_component *third;
30645796c8dcSSimon Schubert 
3065*ef5ccd6cSJohn Marino 	    if (!strcmp (code, "qu"))
3066*ef5ccd6cSJohn Marino 	      {
3067*ef5ccd6cSJohn Marino 		/* ?: expression.  */
30685796c8dcSSimon Schubert 		first = d_expression (di);
30695796c8dcSSimon Schubert 		second = d_expression (di);
3070*ef5ccd6cSJohn Marino 		third = d_expression (di);
3071*ef5ccd6cSJohn Marino 	      }
3072*ef5ccd6cSJohn Marino 	    else if (code[0] == 'n')
3073*ef5ccd6cSJohn Marino 	      {
3074*ef5ccd6cSJohn Marino 		/* new-expression.  */
3075*ef5ccd6cSJohn Marino 		if (code[1] != 'w' && code[1] != 'a')
3076*ef5ccd6cSJohn Marino 		  return NULL;
3077*ef5ccd6cSJohn Marino 		first = d_exprlist (di, '_');
3078*ef5ccd6cSJohn Marino 		second = cplus_demangle_type (di);
3079*ef5ccd6cSJohn Marino 		if (d_peek_char (di) == 'E')
3080*ef5ccd6cSJohn Marino 		  {
3081*ef5ccd6cSJohn Marino 		    d_advance (di, 1);
3082*ef5ccd6cSJohn Marino 		    third = NULL;
3083*ef5ccd6cSJohn Marino 		  }
3084*ef5ccd6cSJohn Marino 		else if (d_peek_char (di) == 'p'
3085*ef5ccd6cSJohn Marino 			 && d_peek_next_char (di) == 'i')
3086*ef5ccd6cSJohn Marino 		  {
3087*ef5ccd6cSJohn Marino 		    /* Parenthesized initializer.  */
3088*ef5ccd6cSJohn Marino 		    d_advance (di, 2);
3089*ef5ccd6cSJohn Marino 		    third = d_exprlist (di, 'E');
3090*ef5ccd6cSJohn Marino 		  }
3091*ef5ccd6cSJohn Marino 		else if (d_peek_char (di) == 'i'
3092*ef5ccd6cSJohn Marino 			 && d_peek_next_char (di) == 'l')
3093*ef5ccd6cSJohn Marino 		  /* initializer-list.  */
3094*ef5ccd6cSJohn Marino 		  third = d_expression (di);
3095*ef5ccd6cSJohn Marino 		else
3096*ef5ccd6cSJohn Marino 		  return NULL;
3097*ef5ccd6cSJohn Marino 	      }
3098*ef5ccd6cSJohn Marino 	    else
3099*ef5ccd6cSJohn Marino 	      return NULL;
31005796c8dcSSimon Schubert 	    return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op,
31015796c8dcSSimon Schubert 				d_make_comp (di,
31025796c8dcSSimon Schubert 					     DEMANGLE_COMPONENT_TRINARY_ARG1,
31035796c8dcSSimon Schubert 					     first,
31045796c8dcSSimon Schubert 					     d_make_comp (di,
31055796c8dcSSimon Schubert 							  DEMANGLE_COMPONENT_TRINARY_ARG2,
3106*ef5ccd6cSJohn Marino 							  second, third)));
31075796c8dcSSimon Schubert 	  }
31085796c8dcSSimon Schubert 	default:
31095796c8dcSSimon Schubert 	  return NULL;
31105796c8dcSSimon Schubert 	}
31115796c8dcSSimon Schubert     }
31125796c8dcSSimon Schubert }
31135796c8dcSSimon Schubert 
31145796c8dcSSimon Schubert /* <expr-primary> ::= L <type> <(value) number> E
31155796c8dcSSimon Schubert                   ::= L <type> <(value) float> E
31165796c8dcSSimon Schubert                   ::= L <mangled-name> E
31175796c8dcSSimon Schubert */
31185796c8dcSSimon Schubert 
31195796c8dcSSimon Schubert static struct demangle_component *
d_expr_primary(struct d_info * di)31205796c8dcSSimon Schubert d_expr_primary (struct d_info *di)
31215796c8dcSSimon Schubert {
31225796c8dcSSimon Schubert   struct demangle_component *ret;
31235796c8dcSSimon Schubert 
31245796c8dcSSimon Schubert   if (! d_check_char (di, 'L'))
31255796c8dcSSimon Schubert     return NULL;
31265796c8dcSSimon Schubert   if (d_peek_char (di) == '_'
31275796c8dcSSimon Schubert       /* Workaround for G++ bug; see comment in write_template_arg.  */
31285796c8dcSSimon Schubert       || d_peek_char (di) == 'Z')
31295796c8dcSSimon Schubert     ret = cplus_demangle_mangled_name (di, 0);
31305796c8dcSSimon Schubert   else
31315796c8dcSSimon Schubert     {
31325796c8dcSSimon Schubert       struct demangle_component *type;
31335796c8dcSSimon Schubert       enum demangle_component_type t;
31345796c8dcSSimon Schubert       const char *s;
31355796c8dcSSimon Schubert 
31365796c8dcSSimon Schubert       type = cplus_demangle_type (di);
31375796c8dcSSimon Schubert       if (type == NULL)
31385796c8dcSSimon Schubert 	return NULL;
31395796c8dcSSimon Schubert 
31405796c8dcSSimon Schubert       /* If we have a type we know how to print, we aren't going to
31415796c8dcSSimon Schubert 	 print the type name itself.  */
31425796c8dcSSimon Schubert       if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
31435796c8dcSSimon Schubert 	  && type->u.s_builtin.type->print != D_PRINT_DEFAULT)
31445796c8dcSSimon Schubert 	di->expansion -= type->u.s_builtin.type->len;
31455796c8dcSSimon Schubert 
31465796c8dcSSimon Schubert       /* Rather than try to interpret the literal value, we just
31475796c8dcSSimon Schubert 	 collect it as a string.  Note that it's possible to have a
31485796c8dcSSimon Schubert 	 floating point literal here.  The ABI specifies that the
31495796c8dcSSimon Schubert 	 format of such literals is machine independent.  That's fine,
31505796c8dcSSimon Schubert 	 but what's not fine is that versions of g++ up to 3.2 with
31515796c8dcSSimon Schubert 	 -fabi-version=1 used upper case letters in the hex constant,
31525796c8dcSSimon Schubert 	 and dumped out gcc's internal representation.  That makes it
31535796c8dcSSimon Schubert 	 hard to tell where the constant ends, and hard to dump the
31545796c8dcSSimon Schubert 	 constant in any readable form anyhow.  We don't attempt to
31555796c8dcSSimon Schubert 	 handle these cases.  */
31565796c8dcSSimon Schubert 
31575796c8dcSSimon Schubert       t = DEMANGLE_COMPONENT_LITERAL;
31585796c8dcSSimon Schubert       if (d_peek_char (di) == 'n')
31595796c8dcSSimon Schubert 	{
31605796c8dcSSimon Schubert 	  t = DEMANGLE_COMPONENT_LITERAL_NEG;
31615796c8dcSSimon Schubert 	  d_advance (di, 1);
31625796c8dcSSimon Schubert 	}
31635796c8dcSSimon Schubert       s = d_str (di);
31645796c8dcSSimon Schubert       while (d_peek_char (di) != 'E')
31655796c8dcSSimon Schubert 	{
31665796c8dcSSimon Schubert 	  if (d_peek_char (di) == '\0')
31675796c8dcSSimon Schubert 	    return NULL;
31685796c8dcSSimon Schubert 	  d_advance (di, 1);
31695796c8dcSSimon Schubert 	}
31705796c8dcSSimon Schubert       ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s));
31715796c8dcSSimon Schubert     }
31725796c8dcSSimon Schubert   if (! d_check_char (di, 'E'))
31735796c8dcSSimon Schubert     return NULL;
31745796c8dcSSimon Schubert   return ret;
31755796c8dcSSimon Schubert }
31765796c8dcSSimon Schubert 
31775796c8dcSSimon Schubert /* <local-name> ::= Z <(function) encoding> E <(entity) name> [<discriminator>]
31785796c8dcSSimon Schubert                 ::= Z <(function) encoding> E s [<discriminator>]
3179*ef5ccd6cSJohn Marino                 ::= Z <(function) encoding> E d [<parameter> number>] _ <entity name>
31805796c8dcSSimon Schubert */
31815796c8dcSSimon Schubert 
31825796c8dcSSimon Schubert static struct demangle_component *
d_local_name(struct d_info * di)31835796c8dcSSimon Schubert d_local_name (struct d_info *di)
31845796c8dcSSimon Schubert {
31855796c8dcSSimon Schubert   struct demangle_component *function;
31865796c8dcSSimon Schubert 
31875796c8dcSSimon Schubert   if (! d_check_char (di, 'Z'))
31885796c8dcSSimon Schubert     return NULL;
31895796c8dcSSimon Schubert 
31905796c8dcSSimon Schubert   function = d_encoding (di, 0);
31915796c8dcSSimon Schubert 
31925796c8dcSSimon Schubert   if (! d_check_char (di, 'E'))
31935796c8dcSSimon Schubert     return NULL;
31945796c8dcSSimon Schubert 
31955796c8dcSSimon Schubert   if (d_peek_char (di) == 's')
31965796c8dcSSimon Schubert     {
31975796c8dcSSimon Schubert       d_advance (di, 1);
31985796c8dcSSimon Schubert       if (! d_discriminator (di))
31995796c8dcSSimon Schubert 	return NULL;
32005796c8dcSSimon Schubert       return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function,
32015796c8dcSSimon Schubert 			  d_make_name (di, "string literal",
32025796c8dcSSimon Schubert 				       sizeof "string literal" - 1));
32035796c8dcSSimon Schubert     }
32045796c8dcSSimon Schubert   else
32055796c8dcSSimon Schubert     {
32065796c8dcSSimon Schubert       struct demangle_component *name;
3207cf7f2e2dSJohn Marino       int num = -1;
3208cf7f2e2dSJohn Marino 
3209cf7f2e2dSJohn Marino       if (d_peek_char (di) == 'd')
3210cf7f2e2dSJohn Marino 	{
3211cf7f2e2dSJohn Marino 	  /* Default argument scope: d <number> _.  */
3212cf7f2e2dSJohn Marino 	  d_advance (di, 1);
3213cf7f2e2dSJohn Marino 	  num = d_compact_number (di);
3214cf7f2e2dSJohn Marino 	  if (num < 0)
3215cf7f2e2dSJohn Marino 	    return NULL;
3216cf7f2e2dSJohn Marino 	}
32175796c8dcSSimon Schubert 
32185796c8dcSSimon Schubert       name = d_name (di);
3219cf7f2e2dSJohn Marino       if (name)
3220cf7f2e2dSJohn Marino 	switch (name->type)
3221cf7f2e2dSJohn Marino 	  {
3222cf7f2e2dSJohn Marino 	    /* Lambdas and unnamed types have internal discriminators.  */
3223cf7f2e2dSJohn Marino 	  case DEMANGLE_COMPONENT_LAMBDA:
3224cf7f2e2dSJohn Marino 	  case DEMANGLE_COMPONENT_UNNAMED_TYPE:
3225cf7f2e2dSJohn Marino 	    break;
3226cf7f2e2dSJohn Marino 	  default:
32275796c8dcSSimon Schubert 	    if (! d_discriminator (di))
32285796c8dcSSimon Schubert 	      return NULL;
3229cf7f2e2dSJohn Marino 	  }
3230cf7f2e2dSJohn Marino       if (num >= 0)
3231cf7f2e2dSJohn Marino 	name = d_make_default_arg (di, num, name);
32325796c8dcSSimon Schubert       return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name);
32335796c8dcSSimon Schubert     }
32345796c8dcSSimon Schubert }
32355796c8dcSSimon Schubert 
32365796c8dcSSimon Schubert /* <discriminator> ::= _ <(non-negative) number>
32375796c8dcSSimon Schubert 
32385796c8dcSSimon Schubert    We demangle the discriminator, but we don't print it out.  FIXME:
32395796c8dcSSimon Schubert    We should print it out in verbose mode.  */
32405796c8dcSSimon Schubert 
32415796c8dcSSimon Schubert static int
d_discriminator(struct d_info * di)32425796c8dcSSimon Schubert d_discriminator (struct d_info *di)
32435796c8dcSSimon Schubert {
32445796c8dcSSimon Schubert   long discrim;
32455796c8dcSSimon Schubert 
32465796c8dcSSimon Schubert   if (d_peek_char (di) != '_')
32475796c8dcSSimon Schubert     return 1;
32485796c8dcSSimon Schubert   d_advance (di, 1);
32495796c8dcSSimon Schubert   discrim = d_number (di);
32505796c8dcSSimon Schubert   if (discrim < 0)
32515796c8dcSSimon Schubert     return 0;
32525796c8dcSSimon Schubert   return 1;
32535796c8dcSSimon Schubert }
32545796c8dcSSimon Schubert 
3255cf7f2e2dSJohn Marino /* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ */
3256cf7f2e2dSJohn Marino 
3257cf7f2e2dSJohn Marino static struct demangle_component *
d_lambda(struct d_info * di)3258cf7f2e2dSJohn Marino d_lambda (struct d_info *di)
3259cf7f2e2dSJohn Marino {
3260cf7f2e2dSJohn Marino   struct demangle_component *tl;
3261cf7f2e2dSJohn Marino   struct demangle_component *ret;
3262cf7f2e2dSJohn Marino   int num;
3263cf7f2e2dSJohn Marino 
3264cf7f2e2dSJohn Marino   if (! d_check_char (di, 'U'))
3265cf7f2e2dSJohn Marino     return NULL;
3266cf7f2e2dSJohn Marino   if (! d_check_char (di, 'l'))
3267cf7f2e2dSJohn Marino     return NULL;
3268cf7f2e2dSJohn Marino 
3269cf7f2e2dSJohn Marino   tl = d_parmlist (di);
3270cf7f2e2dSJohn Marino   if (tl == NULL)
3271cf7f2e2dSJohn Marino     return NULL;
3272cf7f2e2dSJohn Marino 
3273cf7f2e2dSJohn Marino   if (! d_check_char (di, 'E'))
3274cf7f2e2dSJohn Marino     return NULL;
3275cf7f2e2dSJohn Marino 
3276cf7f2e2dSJohn Marino   num = d_compact_number (di);
3277cf7f2e2dSJohn Marino   if (num < 0)
3278cf7f2e2dSJohn Marino     return NULL;
3279cf7f2e2dSJohn Marino 
3280cf7f2e2dSJohn Marino   ret = d_make_empty (di);
3281cf7f2e2dSJohn Marino   if (ret)
3282cf7f2e2dSJohn Marino     {
3283cf7f2e2dSJohn Marino       ret->type = DEMANGLE_COMPONENT_LAMBDA;
3284cf7f2e2dSJohn Marino       ret->u.s_unary_num.sub = tl;
3285cf7f2e2dSJohn Marino       ret->u.s_unary_num.num = num;
3286cf7f2e2dSJohn Marino     }
3287cf7f2e2dSJohn Marino 
3288cf7f2e2dSJohn Marino   if (! d_add_substitution (di, ret))
3289cf7f2e2dSJohn Marino     return NULL;
3290cf7f2e2dSJohn Marino 
3291cf7f2e2dSJohn Marino   return ret;
3292cf7f2e2dSJohn Marino }
3293cf7f2e2dSJohn Marino 
3294cf7f2e2dSJohn Marino /* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */
3295cf7f2e2dSJohn Marino 
3296cf7f2e2dSJohn Marino static struct demangle_component *
d_unnamed_type(struct d_info * di)3297cf7f2e2dSJohn Marino d_unnamed_type (struct d_info *di)
3298cf7f2e2dSJohn Marino {
3299cf7f2e2dSJohn Marino   struct demangle_component *ret;
3300cf7f2e2dSJohn Marino   long num;
3301cf7f2e2dSJohn Marino 
3302cf7f2e2dSJohn Marino   if (! d_check_char (di, 'U'))
3303cf7f2e2dSJohn Marino     return NULL;
3304cf7f2e2dSJohn Marino   if (! d_check_char (di, 't'))
3305cf7f2e2dSJohn Marino     return NULL;
3306cf7f2e2dSJohn Marino 
3307cf7f2e2dSJohn Marino   num = d_compact_number (di);
3308cf7f2e2dSJohn Marino   if (num < 0)
3309cf7f2e2dSJohn Marino     return NULL;
3310cf7f2e2dSJohn Marino 
3311cf7f2e2dSJohn Marino   ret = d_make_empty (di);
3312cf7f2e2dSJohn Marino   if (ret)
3313cf7f2e2dSJohn Marino     {
3314cf7f2e2dSJohn Marino       ret->type = DEMANGLE_COMPONENT_UNNAMED_TYPE;
3315cf7f2e2dSJohn Marino       ret->u.s_number.number = num;
3316cf7f2e2dSJohn Marino     }
3317cf7f2e2dSJohn Marino 
3318cf7f2e2dSJohn Marino   if (! d_add_substitution (di, ret))
3319cf7f2e2dSJohn Marino     return NULL;
3320cf7f2e2dSJohn Marino 
3321cf7f2e2dSJohn Marino   return ret;
3322cf7f2e2dSJohn Marino }
3323cf7f2e2dSJohn Marino 
3324a45ae5f8SJohn Marino /* <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]*
3325a45ae5f8SJohn Marino */
3326a45ae5f8SJohn Marino 
3327a45ae5f8SJohn Marino static struct demangle_component *
d_clone_suffix(struct d_info * di,struct demangle_component * encoding)3328a45ae5f8SJohn Marino d_clone_suffix (struct d_info *di, struct demangle_component *encoding)
3329a45ae5f8SJohn Marino {
3330a45ae5f8SJohn Marino   const char *suffix = d_str (di);
3331a45ae5f8SJohn Marino   const char *pend = suffix;
3332a45ae5f8SJohn Marino   struct demangle_component *n;
3333a45ae5f8SJohn Marino 
3334a45ae5f8SJohn Marino   if (*pend == '.' && (IS_LOWER (pend[1]) || pend[1] == '_'))
3335a45ae5f8SJohn Marino     {
3336a45ae5f8SJohn Marino       pend += 2;
3337a45ae5f8SJohn Marino       while (IS_LOWER (*pend) || *pend == '_')
3338a45ae5f8SJohn Marino 	++pend;
3339a45ae5f8SJohn Marino     }
3340a45ae5f8SJohn Marino   while (*pend == '.' && IS_DIGIT (pend[1]))
3341a45ae5f8SJohn Marino     {
3342a45ae5f8SJohn Marino       pend += 2;
3343a45ae5f8SJohn Marino       while (IS_DIGIT (*pend))
3344a45ae5f8SJohn Marino 	++pend;
3345a45ae5f8SJohn Marino     }
3346a45ae5f8SJohn Marino   d_advance (di, pend - suffix);
3347a45ae5f8SJohn Marino   n = d_make_name (di, suffix, pend - suffix);
3348a45ae5f8SJohn Marino   return d_make_comp (di, DEMANGLE_COMPONENT_CLONE, encoding, n);
3349a45ae5f8SJohn Marino }
3350a45ae5f8SJohn Marino 
33515796c8dcSSimon Schubert /* Add a new substitution.  */
33525796c8dcSSimon Schubert 
33535796c8dcSSimon Schubert static int
d_add_substitution(struct d_info * di,struct demangle_component * dc)33545796c8dcSSimon Schubert d_add_substitution (struct d_info *di, struct demangle_component *dc)
33555796c8dcSSimon Schubert {
33565796c8dcSSimon Schubert   if (dc == NULL)
33575796c8dcSSimon Schubert     return 0;
33585796c8dcSSimon Schubert   if (di->next_sub >= di->num_subs)
33595796c8dcSSimon Schubert     return 0;
33605796c8dcSSimon Schubert   di->subs[di->next_sub] = dc;
33615796c8dcSSimon Schubert   ++di->next_sub;
33625796c8dcSSimon Schubert   return 1;
33635796c8dcSSimon Schubert }
33645796c8dcSSimon Schubert 
33655796c8dcSSimon Schubert /* <substitution> ::= S <seq-id> _
33665796c8dcSSimon Schubert                   ::= S_
33675796c8dcSSimon Schubert                   ::= St
33685796c8dcSSimon Schubert                   ::= Sa
33695796c8dcSSimon Schubert                   ::= Sb
33705796c8dcSSimon Schubert                   ::= Ss
33715796c8dcSSimon Schubert                   ::= Si
33725796c8dcSSimon Schubert                   ::= So
33735796c8dcSSimon Schubert                   ::= Sd
33745796c8dcSSimon Schubert 
33755796c8dcSSimon Schubert    If PREFIX is non-zero, then this type is being used as a prefix in
33765796c8dcSSimon Schubert    a qualified name.  In this case, for the standard substitutions, we
33775796c8dcSSimon Schubert    need to check whether we are being used as a prefix for a
33785796c8dcSSimon Schubert    constructor or destructor, and return a full template name.
33795796c8dcSSimon Schubert    Otherwise we will get something like std::iostream::~iostream()
33805796c8dcSSimon Schubert    which does not correspond particularly well to any function which
33815796c8dcSSimon Schubert    actually appears in the source.
33825796c8dcSSimon Schubert */
33835796c8dcSSimon Schubert 
33845796c8dcSSimon Schubert static const struct d_standard_sub_info standard_subs[] =
33855796c8dcSSimon Schubert {
33865796c8dcSSimon Schubert   { 't', NL ("std"),
33875796c8dcSSimon Schubert     NL ("std"),
33885796c8dcSSimon Schubert     NULL, 0 },
33895796c8dcSSimon Schubert   { 'a', NL ("std::allocator"),
33905796c8dcSSimon Schubert     NL ("std::allocator"),
33915796c8dcSSimon Schubert     NL ("allocator") },
33925796c8dcSSimon Schubert   { 'b', NL ("std::basic_string"),
33935796c8dcSSimon Schubert     NL ("std::basic_string"),
33945796c8dcSSimon Schubert     NL ("basic_string") },
33955796c8dcSSimon Schubert   { 's', NL ("std::string"),
33965796c8dcSSimon Schubert     NL ("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
33975796c8dcSSimon Schubert     NL ("basic_string") },
33985796c8dcSSimon Schubert   { 'i', NL ("std::istream"),
33995796c8dcSSimon Schubert     NL ("std::basic_istream<char, std::char_traits<char> >"),
34005796c8dcSSimon Schubert     NL ("basic_istream") },
34015796c8dcSSimon Schubert   { 'o', NL ("std::ostream"),
34025796c8dcSSimon Schubert     NL ("std::basic_ostream<char, std::char_traits<char> >"),
34035796c8dcSSimon Schubert     NL ("basic_ostream") },
34045796c8dcSSimon Schubert   { 'd', NL ("std::iostream"),
34055796c8dcSSimon Schubert     NL ("std::basic_iostream<char, std::char_traits<char> >"),
34065796c8dcSSimon Schubert     NL ("basic_iostream") }
34075796c8dcSSimon Schubert };
34085796c8dcSSimon Schubert 
34095796c8dcSSimon Schubert static struct demangle_component *
d_substitution(struct d_info * di,int prefix)34105796c8dcSSimon Schubert d_substitution (struct d_info *di, int prefix)
34115796c8dcSSimon Schubert {
34125796c8dcSSimon Schubert   char c;
34135796c8dcSSimon Schubert 
34145796c8dcSSimon Schubert   if (! d_check_char (di, 'S'))
34155796c8dcSSimon Schubert     return NULL;
34165796c8dcSSimon Schubert 
34175796c8dcSSimon Schubert   c = d_next_char (di);
34185796c8dcSSimon Schubert   if (c == '_' || IS_DIGIT (c) || IS_UPPER (c))
34195796c8dcSSimon Schubert     {
34205796c8dcSSimon Schubert       unsigned int id;
34215796c8dcSSimon Schubert 
34225796c8dcSSimon Schubert       id = 0;
34235796c8dcSSimon Schubert       if (c != '_')
34245796c8dcSSimon Schubert 	{
34255796c8dcSSimon Schubert 	  do
34265796c8dcSSimon Schubert 	    {
34275796c8dcSSimon Schubert 	      unsigned int new_id;
34285796c8dcSSimon Schubert 
34295796c8dcSSimon Schubert 	      if (IS_DIGIT (c))
34305796c8dcSSimon Schubert 		new_id = id * 36 + c - '0';
34315796c8dcSSimon Schubert 	      else if (IS_UPPER (c))
34325796c8dcSSimon Schubert 		new_id = id * 36 + c - 'A' + 10;
34335796c8dcSSimon Schubert 	      else
34345796c8dcSSimon Schubert 		return NULL;
34355796c8dcSSimon Schubert 	      if (new_id < id)
34365796c8dcSSimon Schubert 		return NULL;
34375796c8dcSSimon Schubert 	      id = new_id;
34385796c8dcSSimon Schubert 	      c = d_next_char (di);
34395796c8dcSSimon Schubert 	    }
34405796c8dcSSimon Schubert 	  while (c != '_');
34415796c8dcSSimon Schubert 
34425796c8dcSSimon Schubert 	  ++id;
34435796c8dcSSimon Schubert 	}
34445796c8dcSSimon Schubert 
34455796c8dcSSimon Schubert       if (id >= (unsigned int) di->next_sub)
34465796c8dcSSimon Schubert 	return NULL;
34475796c8dcSSimon Schubert 
34485796c8dcSSimon Schubert       ++di->did_subs;
34495796c8dcSSimon Schubert 
34505796c8dcSSimon Schubert       return di->subs[id];
34515796c8dcSSimon Schubert     }
34525796c8dcSSimon Schubert   else
34535796c8dcSSimon Schubert     {
34545796c8dcSSimon Schubert       int verbose;
34555796c8dcSSimon Schubert       const struct d_standard_sub_info *p;
34565796c8dcSSimon Schubert       const struct d_standard_sub_info *pend;
34575796c8dcSSimon Schubert 
34585796c8dcSSimon Schubert       verbose = (di->options & DMGL_VERBOSE) != 0;
34595796c8dcSSimon Schubert       if (! verbose && prefix)
34605796c8dcSSimon Schubert 	{
34615796c8dcSSimon Schubert 	  char peek;
34625796c8dcSSimon Schubert 
34635796c8dcSSimon Schubert 	  peek = d_peek_char (di);
34645796c8dcSSimon Schubert 	  if (peek == 'C' || peek == 'D')
34655796c8dcSSimon Schubert 	    verbose = 1;
34665796c8dcSSimon Schubert 	}
34675796c8dcSSimon Schubert 
34685796c8dcSSimon Schubert       pend = (&standard_subs[0]
34695796c8dcSSimon Schubert 	      + sizeof standard_subs / sizeof standard_subs[0]);
34705796c8dcSSimon Schubert       for (p = &standard_subs[0]; p < pend; ++p)
34715796c8dcSSimon Schubert 	{
34725796c8dcSSimon Schubert 	  if (c == p->code)
34735796c8dcSSimon Schubert 	    {
34745796c8dcSSimon Schubert 	      const char *s;
34755796c8dcSSimon Schubert 	      int len;
34765796c8dcSSimon Schubert 
34775796c8dcSSimon Schubert 	      if (p->set_last_name != NULL)
34785796c8dcSSimon Schubert 		di->last_name = d_make_sub (di, p->set_last_name,
34795796c8dcSSimon Schubert 					    p->set_last_name_len);
34805796c8dcSSimon Schubert 	      if (verbose)
34815796c8dcSSimon Schubert 		{
34825796c8dcSSimon Schubert 		  s = p->full_expansion;
34835796c8dcSSimon Schubert 		  len = p->full_len;
34845796c8dcSSimon Schubert 		}
34855796c8dcSSimon Schubert 	      else
34865796c8dcSSimon Schubert 		{
34875796c8dcSSimon Schubert 		  s = p->simple_expansion;
34885796c8dcSSimon Schubert 		  len = p->simple_len;
34895796c8dcSSimon Schubert 		}
34905796c8dcSSimon Schubert 	      di->expansion += len;
34915796c8dcSSimon Schubert 	      return d_make_sub (di, s, len);
34925796c8dcSSimon Schubert 	    }
34935796c8dcSSimon Schubert 	}
34945796c8dcSSimon Schubert 
34955796c8dcSSimon Schubert       return NULL;
34965796c8dcSSimon Schubert     }
34975796c8dcSSimon Schubert }
34985796c8dcSSimon Schubert 
34995796c8dcSSimon Schubert /* Initialize a growable string.  */
35005796c8dcSSimon Schubert 
35015796c8dcSSimon Schubert static void
d_growable_string_init(struct d_growable_string * dgs,size_t estimate)35025796c8dcSSimon Schubert d_growable_string_init (struct d_growable_string *dgs, size_t estimate)
35035796c8dcSSimon Schubert {
35045796c8dcSSimon Schubert   dgs->buf = NULL;
35055796c8dcSSimon Schubert   dgs->len = 0;
35065796c8dcSSimon Schubert   dgs->alc = 0;
35075796c8dcSSimon Schubert   dgs->allocation_failure = 0;
35085796c8dcSSimon Schubert 
35095796c8dcSSimon Schubert   if (estimate > 0)
35105796c8dcSSimon Schubert     d_growable_string_resize (dgs, estimate);
35115796c8dcSSimon Schubert }
35125796c8dcSSimon Schubert 
35135796c8dcSSimon Schubert /* Grow a growable string to a given size.  */
35145796c8dcSSimon Schubert 
35155796c8dcSSimon Schubert static inline void
d_growable_string_resize(struct d_growable_string * dgs,size_t need)35165796c8dcSSimon Schubert d_growable_string_resize (struct d_growable_string *dgs, size_t need)
35175796c8dcSSimon Schubert {
35185796c8dcSSimon Schubert   size_t newalc;
35195796c8dcSSimon Schubert   char *newbuf;
35205796c8dcSSimon Schubert 
35215796c8dcSSimon Schubert   if (dgs->allocation_failure)
35225796c8dcSSimon Schubert     return;
35235796c8dcSSimon Schubert 
35245796c8dcSSimon Schubert   /* Start allocation at two bytes to avoid any possibility of confusion
35255796c8dcSSimon Schubert      with the special value of 1 used as a return in *palc to indicate
35265796c8dcSSimon Schubert      allocation failures.  */
35275796c8dcSSimon Schubert   newalc = dgs->alc > 0 ? dgs->alc : 2;
35285796c8dcSSimon Schubert   while (newalc < need)
35295796c8dcSSimon Schubert     newalc <<= 1;
35305796c8dcSSimon Schubert 
35315796c8dcSSimon Schubert   newbuf = (char *) realloc (dgs->buf, newalc);
35325796c8dcSSimon Schubert   if (newbuf == NULL)
35335796c8dcSSimon Schubert     {
35345796c8dcSSimon Schubert       free (dgs->buf);
35355796c8dcSSimon Schubert       dgs->buf = NULL;
35365796c8dcSSimon Schubert       dgs->len = 0;
35375796c8dcSSimon Schubert       dgs->alc = 0;
35385796c8dcSSimon Schubert       dgs->allocation_failure = 1;
35395796c8dcSSimon Schubert       return;
35405796c8dcSSimon Schubert     }
35415796c8dcSSimon Schubert   dgs->buf = newbuf;
35425796c8dcSSimon Schubert   dgs->alc = newalc;
35435796c8dcSSimon Schubert }
35445796c8dcSSimon Schubert 
35455796c8dcSSimon Schubert /* Append a buffer to a growable string.  */
35465796c8dcSSimon Schubert 
35475796c8dcSSimon Schubert static inline void
d_growable_string_append_buffer(struct d_growable_string * dgs,const char * s,size_t l)35485796c8dcSSimon Schubert d_growable_string_append_buffer (struct d_growable_string *dgs,
35495796c8dcSSimon Schubert                                  const char *s, size_t l)
35505796c8dcSSimon Schubert {
35515796c8dcSSimon Schubert   size_t need;
35525796c8dcSSimon Schubert 
35535796c8dcSSimon Schubert   need = dgs->len + l + 1;
35545796c8dcSSimon Schubert   if (need > dgs->alc)
35555796c8dcSSimon Schubert     d_growable_string_resize (dgs, need);
35565796c8dcSSimon Schubert 
35575796c8dcSSimon Schubert   if (dgs->allocation_failure)
35585796c8dcSSimon Schubert     return;
35595796c8dcSSimon Schubert 
35605796c8dcSSimon Schubert   memcpy (dgs->buf + dgs->len, s, l);
35615796c8dcSSimon Schubert   dgs->buf[dgs->len + l] = '\0';
35625796c8dcSSimon Schubert   dgs->len += l;
35635796c8dcSSimon Schubert }
35645796c8dcSSimon Schubert 
35655796c8dcSSimon Schubert /* Bridge growable strings to the callback mechanism.  */
35665796c8dcSSimon Schubert 
35675796c8dcSSimon Schubert static void
d_growable_string_callback_adapter(const char * s,size_t l,void * opaque)35685796c8dcSSimon Schubert d_growable_string_callback_adapter (const char *s, size_t l, void *opaque)
35695796c8dcSSimon Schubert {
35705796c8dcSSimon Schubert   struct d_growable_string *dgs = (struct d_growable_string*) opaque;
35715796c8dcSSimon Schubert 
35725796c8dcSSimon Schubert   d_growable_string_append_buffer (dgs, s, l);
35735796c8dcSSimon Schubert }
35745796c8dcSSimon Schubert 
35755796c8dcSSimon Schubert /* Initialize a print information structure.  */
35765796c8dcSSimon Schubert 
35775796c8dcSSimon Schubert static void
d_print_init(struct d_print_info * dpi,demangle_callbackref callback,void * opaque)3578c50c785cSJohn Marino d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
3579c50c785cSJohn Marino 	      void *opaque)
35805796c8dcSSimon Schubert {
35815796c8dcSSimon Schubert   dpi->len = 0;
35825796c8dcSSimon Schubert   dpi->last_char = '\0';
35835796c8dcSSimon Schubert   dpi->templates = NULL;
35845796c8dcSSimon Schubert   dpi->modifiers = NULL;
3585a45ae5f8SJohn Marino   dpi->pack_index = 0;
3586cf7f2e2dSJohn Marino   dpi->flush_count = 0;
35875796c8dcSSimon Schubert 
35885796c8dcSSimon Schubert   dpi->callback = callback;
35895796c8dcSSimon Schubert   dpi->opaque = opaque;
35905796c8dcSSimon Schubert 
35915796c8dcSSimon Schubert   dpi->demangle_failure = 0;
35925796c8dcSSimon Schubert }
35935796c8dcSSimon Schubert 
35945796c8dcSSimon Schubert /* Indicate that an error occurred during printing, and test for error.  */
35955796c8dcSSimon Schubert 
35965796c8dcSSimon Schubert static inline void
d_print_error(struct d_print_info * dpi)35975796c8dcSSimon Schubert d_print_error (struct d_print_info *dpi)
35985796c8dcSSimon Schubert {
35995796c8dcSSimon Schubert   dpi->demangle_failure = 1;
36005796c8dcSSimon Schubert }
36015796c8dcSSimon Schubert 
36025796c8dcSSimon Schubert static inline int
d_print_saw_error(struct d_print_info * dpi)36035796c8dcSSimon Schubert d_print_saw_error (struct d_print_info *dpi)
36045796c8dcSSimon Schubert {
36055796c8dcSSimon Schubert   return dpi->demangle_failure != 0;
36065796c8dcSSimon Schubert }
36075796c8dcSSimon Schubert 
36085796c8dcSSimon Schubert /* Flush buffered characters to the callback.  */
36095796c8dcSSimon Schubert 
36105796c8dcSSimon Schubert static inline void
d_print_flush(struct d_print_info * dpi)36115796c8dcSSimon Schubert d_print_flush (struct d_print_info *dpi)
36125796c8dcSSimon Schubert {
36135796c8dcSSimon Schubert   dpi->buf[dpi->len] = '\0';
36145796c8dcSSimon Schubert   dpi->callback (dpi->buf, dpi->len, dpi->opaque);
36155796c8dcSSimon Schubert   dpi->len = 0;
3616cf7f2e2dSJohn Marino   dpi->flush_count++;
36175796c8dcSSimon Schubert }
36185796c8dcSSimon Schubert 
36195796c8dcSSimon Schubert /* Append characters and buffers for printing.  */
36205796c8dcSSimon Schubert 
36215796c8dcSSimon Schubert static inline void
d_append_char(struct d_print_info * dpi,char c)36225796c8dcSSimon Schubert d_append_char (struct d_print_info *dpi, char c)
36235796c8dcSSimon Schubert {
36245796c8dcSSimon Schubert   if (dpi->len == sizeof (dpi->buf) - 1)
36255796c8dcSSimon Schubert     d_print_flush (dpi);
36265796c8dcSSimon Schubert 
36275796c8dcSSimon Schubert   dpi->buf[dpi->len++] = c;
36285796c8dcSSimon Schubert   dpi->last_char = c;
36295796c8dcSSimon Schubert }
36305796c8dcSSimon Schubert 
36315796c8dcSSimon Schubert static inline void
d_append_buffer(struct d_print_info * dpi,const char * s,size_t l)36325796c8dcSSimon Schubert d_append_buffer (struct d_print_info *dpi, const char *s, size_t l)
36335796c8dcSSimon Schubert {
36345796c8dcSSimon Schubert   size_t i;
36355796c8dcSSimon Schubert 
36365796c8dcSSimon Schubert   for (i = 0; i < l; i++)
36375796c8dcSSimon Schubert     d_append_char (dpi, s[i]);
36385796c8dcSSimon Schubert }
36395796c8dcSSimon Schubert 
36405796c8dcSSimon Schubert static inline void
d_append_string(struct d_print_info * dpi,const char * s)36415796c8dcSSimon Schubert d_append_string (struct d_print_info *dpi, const char *s)
36425796c8dcSSimon Schubert {
36435796c8dcSSimon Schubert   d_append_buffer (dpi, s, strlen (s));
36445796c8dcSSimon Schubert }
36455796c8dcSSimon Schubert 
3646cf7f2e2dSJohn Marino static inline void
d_append_num(struct d_print_info * dpi,long l)3647cf7f2e2dSJohn Marino d_append_num (struct d_print_info *dpi, long l)
3648cf7f2e2dSJohn Marino {
3649cf7f2e2dSJohn Marino   char buf[25];
3650cf7f2e2dSJohn Marino   sprintf (buf,"%ld", l);
3651cf7f2e2dSJohn Marino   d_append_string (dpi, buf);
3652cf7f2e2dSJohn Marino }
3653cf7f2e2dSJohn Marino 
36545796c8dcSSimon Schubert static inline char
d_last_char(struct d_print_info * dpi)36555796c8dcSSimon Schubert d_last_char (struct d_print_info *dpi)
36565796c8dcSSimon Schubert {
36575796c8dcSSimon Schubert   return dpi->last_char;
36585796c8dcSSimon Schubert }
36595796c8dcSSimon Schubert 
36605796c8dcSSimon Schubert /* Turn components into a human readable string.  OPTIONS is the
36615796c8dcSSimon Schubert    options bits passed to the demangler.  DC is the tree to print.
36625796c8dcSSimon Schubert    CALLBACK is a function to call to flush demangled string segments
36635796c8dcSSimon Schubert    as they fill the intermediate buffer, and OPAQUE is a generalized
36645796c8dcSSimon Schubert    callback argument.  On success, this returns 1.  On failure,
36655796c8dcSSimon Schubert    it returns 0, indicating a bad parse.  It does not use heap
36665796c8dcSSimon Schubert    memory to build an output string, so cannot encounter memory
36675796c8dcSSimon Schubert    allocation failure.  */
36685796c8dcSSimon Schubert 
36695796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
36705796c8dcSSimon Schubert int
cplus_demangle_print_callback(int options,const struct demangle_component * dc,demangle_callbackref callback,void * opaque)36715796c8dcSSimon Schubert cplus_demangle_print_callback (int options,
36725796c8dcSSimon Schubert                                const struct demangle_component *dc,
36735796c8dcSSimon Schubert                                demangle_callbackref callback, void *opaque)
36745796c8dcSSimon Schubert {
36755796c8dcSSimon Schubert   struct d_print_info dpi;
36765796c8dcSSimon Schubert 
3677c50c785cSJohn Marino   d_print_init (&dpi, callback, opaque);
36785796c8dcSSimon Schubert 
3679c50c785cSJohn Marino   d_print_comp (&dpi, options, dc);
36805796c8dcSSimon Schubert 
36815796c8dcSSimon Schubert   d_print_flush (&dpi);
36825796c8dcSSimon Schubert 
36835796c8dcSSimon Schubert   return ! d_print_saw_error (&dpi);
36845796c8dcSSimon Schubert }
36855796c8dcSSimon Schubert 
36865796c8dcSSimon Schubert /* Turn components into a human readable string.  OPTIONS is the
36875796c8dcSSimon Schubert    options bits passed to the demangler.  DC is the tree to print.
36885796c8dcSSimon Schubert    ESTIMATE is a guess at the length of the result.  This returns a
36895796c8dcSSimon Schubert    string allocated by malloc, or NULL on error.  On success, this
36905796c8dcSSimon Schubert    sets *PALC to the size of the allocated buffer.  On failure, this
36915796c8dcSSimon Schubert    sets *PALC to 0 for a bad parse, or to 1 for a memory allocation
36925796c8dcSSimon Schubert    failure.  */
36935796c8dcSSimon Schubert 
36945796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
36955796c8dcSSimon Schubert char *
cplus_demangle_print(int options,const struct demangle_component * dc,int estimate,size_t * palc)36965796c8dcSSimon Schubert cplus_demangle_print (int options, const struct demangle_component *dc,
36975796c8dcSSimon Schubert                       int estimate, size_t *palc)
36985796c8dcSSimon Schubert {
36995796c8dcSSimon Schubert   struct d_growable_string dgs;
37005796c8dcSSimon Schubert 
37015796c8dcSSimon Schubert   d_growable_string_init (&dgs, estimate);
37025796c8dcSSimon Schubert 
37035796c8dcSSimon Schubert   if (! cplus_demangle_print_callback (options, dc,
37045796c8dcSSimon Schubert                                        d_growable_string_callback_adapter,
37055796c8dcSSimon Schubert                                        &dgs))
37065796c8dcSSimon Schubert     {
37075796c8dcSSimon Schubert       free (dgs.buf);
37085796c8dcSSimon Schubert       *palc = 0;
37095796c8dcSSimon Schubert       return NULL;
37105796c8dcSSimon Schubert     }
37115796c8dcSSimon Schubert 
37125796c8dcSSimon Schubert   *palc = dgs.allocation_failure ? 1 : dgs.alc;
37135796c8dcSSimon Schubert   return dgs.buf;
37145796c8dcSSimon Schubert }
37155796c8dcSSimon Schubert 
37165796c8dcSSimon Schubert /* Returns the I'th element of the template arglist ARGS, or NULL on
37175796c8dcSSimon Schubert    failure.  */
37185796c8dcSSimon Schubert 
37195796c8dcSSimon Schubert static struct demangle_component *
d_index_template_argument(struct demangle_component * args,int i)37205796c8dcSSimon Schubert d_index_template_argument (struct demangle_component *args, int i)
37215796c8dcSSimon Schubert {
37225796c8dcSSimon Schubert   struct demangle_component *a;
37235796c8dcSSimon Schubert 
37245796c8dcSSimon Schubert   for (a = args;
37255796c8dcSSimon Schubert        a != NULL;
37265796c8dcSSimon Schubert        a = d_right (a))
37275796c8dcSSimon Schubert     {
37285796c8dcSSimon Schubert       if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
37295796c8dcSSimon Schubert 	return NULL;
37305796c8dcSSimon Schubert       if (i <= 0)
37315796c8dcSSimon Schubert 	break;
37325796c8dcSSimon Schubert       --i;
37335796c8dcSSimon Schubert     }
37345796c8dcSSimon Schubert   if (i != 0 || a == NULL)
37355796c8dcSSimon Schubert     return NULL;
37365796c8dcSSimon Schubert 
37375796c8dcSSimon Schubert   return d_left (a);
37385796c8dcSSimon Schubert }
37395796c8dcSSimon Schubert 
37405796c8dcSSimon Schubert /* Returns the template argument from the current context indicated by DC,
37415796c8dcSSimon Schubert    which is a DEMANGLE_COMPONENT_TEMPLATE_PARAM, or NULL.  */
37425796c8dcSSimon Schubert 
37435796c8dcSSimon Schubert static struct demangle_component *
d_lookup_template_argument(struct d_print_info * dpi,const struct demangle_component * dc)37445796c8dcSSimon Schubert d_lookup_template_argument (struct d_print_info *dpi,
37455796c8dcSSimon Schubert 			    const struct demangle_component *dc)
37465796c8dcSSimon Schubert {
37475796c8dcSSimon Schubert   if (dpi->templates == NULL)
37485796c8dcSSimon Schubert     {
37495796c8dcSSimon Schubert       d_print_error (dpi);
37505796c8dcSSimon Schubert       return NULL;
37515796c8dcSSimon Schubert     }
37525796c8dcSSimon Schubert 
37535796c8dcSSimon Schubert   return d_index_template_argument
37545796c8dcSSimon Schubert     (d_right (dpi->templates->template_decl),
37555796c8dcSSimon Schubert      dc->u.s_number.number);
37565796c8dcSSimon Schubert }
37575796c8dcSSimon Schubert 
37585796c8dcSSimon Schubert /* Returns a template argument pack used in DC (any will do), or NULL.  */
37595796c8dcSSimon Schubert 
37605796c8dcSSimon Schubert static struct demangle_component *
d_find_pack(struct d_print_info * dpi,const struct demangle_component * dc)37615796c8dcSSimon Schubert d_find_pack (struct d_print_info *dpi,
37625796c8dcSSimon Schubert 	     const struct demangle_component *dc)
37635796c8dcSSimon Schubert {
37645796c8dcSSimon Schubert   struct demangle_component *a;
37655796c8dcSSimon Schubert   if (dc == NULL)
37665796c8dcSSimon Schubert     return NULL;
37675796c8dcSSimon Schubert 
37685796c8dcSSimon Schubert   switch (dc->type)
37695796c8dcSSimon Schubert     {
37705796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
37715796c8dcSSimon Schubert       a = d_lookup_template_argument (dpi, dc);
37725796c8dcSSimon Schubert       if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
37735796c8dcSSimon Schubert 	return a;
37745796c8dcSSimon Schubert       return NULL;
37755796c8dcSSimon Schubert 
37765796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_PACK_EXPANSION:
37775796c8dcSSimon Schubert       return NULL;
37785796c8dcSSimon Schubert 
3779c50c785cSJohn Marino     case DEMANGLE_COMPONENT_LAMBDA:
37805796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_NAME:
3781*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TAGGED_NAME:
37825796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_OPERATOR:
37835796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_BUILTIN_TYPE:
37845796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_SUB_STD:
37855796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CHARACTER:
37865796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_FUNCTION_PARAM:
3787*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_UNNAMED_TYPE:
37885796c8dcSSimon Schubert       return NULL;
37895796c8dcSSimon Schubert 
37905796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
37915796c8dcSSimon Schubert       return d_find_pack (dpi, dc->u.s_extended_operator.name);
37925796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CTOR:
37935796c8dcSSimon Schubert       return d_find_pack (dpi, dc->u.s_ctor.name);
37945796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_DTOR:
37955796c8dcSSimon Schubert       return d_find_pack (dpi, dc->u.s_dtor.name);
37965796c8dcSSimon Schubert 
37975796c8dcSSimon Schubert     default:
37985796c8dcSSimon Schubert       a = d_find_pack (dpi, d_left (dc));
37995796c8dcSSimon Schubert       if (a)
38005796c8dcSSimon Schubert 	return a;
38015796c8dcSSimon Schubert       return d_find_pack (dpi, d_right (dc));
38025796c8dcSSimon Schubert     }
38035796c8dcSSimon Schubert }
38045796c8dcSSimon Schubert 
38055796c8dcSSimon Schubert /* Returns the length of the template argument pack DC.  */
38065796c8dcSSimon Schubert 
38075796c8dcSSimon Schubert static int
d_pack_length(const struct demangle_component * dc)38085796c8dcSSimon Schubert d_pack_length (const struct demangle_component *dc)
38095796c8dcSSimon Schubert {
38105796c8dcSSimon Schubert   int count = 0;
38115796c8dcSSimon Schubert   while (dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST
38125796c8dcSSimon Schubert 	 && d_left (dc) != NULL)
38135796c8dcSSimon Schubert     {
38145796c8dcSSimon Schubert       ++count;
38155796c8dcSSimon Schubert       dc = d_right (dc);
38165796c8dcSSimon Schubert     }
38175796c8dcSSimon Schubert   return count;
38185796c8dcSSimon Schubert }
38195796c8dcSSimon Schubert 
38205796c8dcSSimon Schubert /* DC is a component of a mangled expression.  Print it, wrapped in parens
38215796c8dcSSimon Schubert    if needed.  */
38225796c8dcSSimon Schubert 
38235796c8dcSSimon Schubert static void
d_print_subexpr(struct d_print_info * dpi,int options,const struct demangle_component * dc)3824c50c785cSJohn Marino d_print_subexpr (struct d_print_info *dpi, int options,
38255796c8dcSSimon Schubert 		 const struct demangle_component *dc)
38265796c8dcSSimon Schubert {
38275796c8dcSSimon Schubert   int simple = 0;
38285796c8dcSSimon Schubert   if (dc->type == DEMANGLE_COMPONENT_NAME
3829*ef5ccd6cSJohn Marino       || dc->type == DEMANGLE_COMPONENT_QUAL_NAME
3830*ef5ccd6cSJohn Marino       || dc->type == DEMANGLE_COMPONENT_INITIALIZER_LIST
38315796c8dcSSimon Schubert       || dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM)
38325796c8dcSSimon Schubert     simple = 1;
38335796c8dcSSimon Schubert   if (!simple)
38345796c8dcSSimon Schubert     d_append_char (dpi, '(');
3835c50c785cSJohn Marino   d_print_comp (dpi, options, dc);
38365796c8dcSSimon Schubert   if (!simple)
38375796c8dcSSimon Schubert     d_append_char (dpi, ')');
38385796c8dcSSimon Schubert }
38395796c8dcSSimon Schubert 
38405796c8dcSSimon Schubert /* Subroutine to handle components.  */
38415796c8dcSSimon Schubert 
38425796c8dcSSimon Schubert static void
d_print_comp(struct d_print_info * dpi,int options,const struct demangle_component * dc)3843c50c785cSJohn Marino d_print_comp (struct d_print_info *dpi, int options,
38445796c8dcSSimon Schubert               const struct demangle_component *dc)
38455796c8dcSSimon Schubert {
3846a45ae5f8SJohn Marino   /* Magic variable to let reference smashing skip over the next modifier
3847a45ae5f8SJohn Marino      without needing to modify *dc.  */
3848a45ae5f8SJohn Marino   const struct demangle_component *mod_inner = NULL;
3849a45ae5f8SJohn Marino 
38505796c8dcSSimon Schubert   if (dc == NULL)
38515796c8dcSSimon Schubert     {
38525796c8dcSSimon Schubert       d_print_error (dpi);
38535796c8dcSSimon Schubert       return;
38545796c8dcSSimon Schubert     }
38555796c8dcSSimon Schubert   if (d_print_saw_error (dpi))
38565796c8dcSSimon Schubert     return;
38575796c8dcSSimon Schubert 
38585796c8dcSSimon Schubert   switch (dc->type)
38595796c8dcSSimon Schubert     {
38605796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_NAME:
3861c50c785cSJohn Marino       if ((options & DMGL_JAVA) == 0)
38625796c8dcSSimon Schubert 	d_append_buffer (dpi, dc->u.s_name.s, dc->u.s_name.len);
38635796c8dcSSimon Schubert       else
38645796c8dcSSimon Schubert 	d_print_java_identifier (dpi, dc->u.s_name.s, dc->u.s_name.len);
38655796c8dcSSimon Schubert       return;
38665796c8dcSSimon Schubert 
3867*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TAGGED_NAME:
3868*ef5ccd6cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
3869*ef5ccd6cSJohn Marino       d_append_string (dpi, "[abi:");
3870*ef5ccd6cSJohn Marino       d_print_comp (dpi, options, d_right (dc));
3871*ef5ccd6cSJohn Marino       d_append_char (dpi, ']');
3872*ef5ccd6cSJohn Marino       return;
3873*ef5ccd6cSJohn Marino 
38745796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_QUAL_NAME:
38755796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LOCAL_NAME:
3876c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
3877c50c785cSJohn Marino       if ((options & DMGL_JAVA) == 0)
38785796c8dcSSimon Schubert 	d_append_string (dpi, "::");
38795796c8dcSSimon Schubert       else
38805796c8dcSSimon Schubert 	d_append_char (dpi, '.');
3881*ef5ccd6cSJohn Marino       {
3882*ef5ccd6cSJohn Marino 	struct demangle_component *local_name = d_right (dc);
3883*ef5ccd6cSJohn Marino 	if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
3884*ef5ccd6cSJohn Marino 	  {
3885*ef5ccd6cSJohn Marino 	    d_append_string (dpi, "{default arg#");
3886*ef5ccd6cSJohn Marino 	    d_append_num (dpi, local_name->u.s_unary_num.num + 1);
3887*ef5ccd6cSJohn Marino 	    d_append_string (dpi, "}::");
3888*ef5ccd6cSJohn Marino 	    local_name = local_name->u.s_unary_num.sub;
3889*ef5ccd6cSJohn Marino 	  }
3890*ef5ccd6cSJohn Marino 	d_print_comp (dpi, options, local_name);
3891*ef5ccd6cSJohn Marino       }
38925796c8dcSSimon Schubert       return;
38935796c8dcSSimon Schubert 
38945796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPED_NAME:
38955796c8dcSSimon Schubert       {
38965796c8dcSSimon Schubert 	struct d_print_mod *hold_modifiers;
38975796c8dcSSimon Schubert 	struct demangle_component *typed_name;
38985796c8dcSSimon Schubert 	struct d_print_mod adpm[4];
38995796c8dcSSimon Schubert 	unsigned int i;
39005796c8dcSSimon Schubert 	struct d_print_template dpt;
39015796c8dcSSimon Schubert 
39025796c8dcSSimon Schubert 	/* Pass the name down to the type so that it can be printed in
39035796c8dcSSimon Schubert 	   the right place for the type.  We also have to pass down
39045796c8dcSSimon Schubert 	   any CV-qualifiers, which apply to the this parameter.  */
39055796c8dcSSimon Schubert 	hold_modifiers = dpi->modifiers;
39065796c8dcSSimon Schubert 	dpi->modifiers = 0;
39075796c8dcSSimon Schubert 	i = 0;
39085796c8dcSSimon Schubert 	typed_name = d_left (dc);
39095796c8dcSSimon Schubert 	while (typed_name != NULL)
39105796c8dcSSimon Schubert 	  {
39115796c8dcSSimon Schubert 	    if (i >= sizeof adpm / sizeof adpm[0])
39125796c8dcSSimon Schubert 	      {
39135796c8dcSSimon Schubert 		d_print_error (dpi);
39145796c8dcSSimon Schubert 		return;
39155796c8dcSSimon Schubert 	      }
39165796c8dcSSimon Schubert 
39175796c8dcSSimon Schubert 	    adpm[i].next = dpi->modifiers;
39185796c8dcSSimon Schubert 	    dpi->modifiers = &adpm[i];
39195796c8dcSSimon Schubert 	    adpm[i].mod = typed_name;
39205796c8dcSSimon Schubert 	    adpm[i].printed = 0;
39215796c8dcSSimon Schubert 	    adpm[i].templates = dpi->templates;
39225796c8dcSSimon Schubert 	    ++i;
39235796c8dcSSimon Schubert 
39245796c8dcSSimon Schubert 	    if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS
39255796c8dcSSimon Schubert 		&& typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS
39265796c8dcSSimon Schubert 		&& typed_name->type != DEMANGLE_COMPONENT_CONST_THIS)
39275796c8dcSSimon Schubert 	      break;
39285796c8dcSSimon Schubert 
39295796c8dcSSimon Schubert 	    typed_name = d_left (typed_name);
39305796c8dcSSimon Schubert 	  }
39315796c8dcSSimon Schubert 
39325796c8dcSSimon Schubert 	if (typed_name == NULL)
39335796c8dcSSimon Schubert 	  {
39345796c8dcSSimon Schubert 	    d_print_error (dpi);
39355796c8dcSSimon Schubert 	    return;
39365796c8dcSSimon Schubert 	  }
39375796c8dcSSimon Schubert 
39385796c8dcSSimon Schubert 	/* If typed_name is a template, then it applies to the
39395796c8dcSSimon Schubert 	   function type as well.  */
39405796c8dcSSimon Schubert 	if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
39415796c8dcSSimon Schubert 	  {
39425796c8dcSSimon Schubert 	    dpt.next = dpi->templates;
39435796c8dcSSimon Schubert 	    dpi->templates = &dpt;
39445796c8dcSSimon Schubert 	    dpt.template_decl = typed_name;
39455796c8dcSSimon Schubert 	  }
39465796c8dcSSimon Schubert 
39475796c8dcSSimon Schubert 	/* If typed_name is a DEMANGLE_COMPONENT_LOCAL_NAME, then
39485796c8dcSSimon Schubert 	   there may be CV-qualifiers on its right argument which
39495796c8dcSSimon Schubert 	   really apply here; this happens when parsing a class which
39505796c8dcSSimon Schubert 	   is local to a function.  */
39515796c8dcSSimon Schubert 	if (typed_name->type == DEMANGLE_COMPONENT_LOCAL_NAME)
39525796c8dcSSimon Schubert 	  {
39535796c8dcSSimon Schubert 	    struct demangle_component *local_name;
39545796c8dcSSimon Schubert 
39555796c8dcSSimon Schubert 	    local_name = d_right (typed_name);
3956cf7f2e2dSJohn Marino 	    if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
3957cf7f2e2dSJohn Marino 	      local_name = local_name->u.s_unary_num.sub;
39585796c8dcSSimon Schubert 	    while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
39595796c8dcSSimon Schubert 		   || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
39605796c8dcSSimon Schubert 		   || local_name->type == DEMANGLE_COMPONENT_CONST_THIS)
39615796c8dcSSimon Schubert 	      {
39625796c8dcSSimon Schubert 		if (i >= sizeof adpm / sizeof adpm[0])
39635796c8dcSSimon Schubert 		  {
39645796c8dcSSimon Schubert 		    d_print_error (dpi);
39655796c8dcSSimon Schubert 		    return;
39665796c8dcSSimon Schubert 		  }
39675796c8dcSSimon Schubert 
39685796c8dcSSimon Schubert 		adpm[i] = adpm[i - 1];
39695796c8dcSSimon Schubert 		adpm[i].next = &adpm[i - 1];
39705796c8dcSSimon Schubert 		dpi->modifiers = &adpm[i];
39715796c8dcSSimon Schubert 
39725796c8dcSSimon Schubert 		adpm[i - 1].mod = local_name;
39735796c8dcSSimon Schubert 		adpm[i - 1].printed = 0;
39745796c8dcSSimon Schubert 		adpm[i - 1].templates = dpi->templates;
39755796c8dcSSimon Schubert 		++i;
39765796c8dcSSimon Schubert 
39775796c8dcSSimon Schubert 		local_name = d_left (local_name);
39785796c8dcSSimon Schubert 	      }
39795796c8dcSSimon Schubert 	  }
39805796c8dcSSimon Schubert 
3981c50c785cSJohn Marino 	d_print_comp (dpi, options, d_right (dc));
39825796c8dcSSimon Schubert 
39835796c8dcSSimon Schubert 	if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
39845796c8dcSSimon Schubert 	  dpi->templates = dpt.next;
39855796c8dcSSimon Schubert 
39865796c8dcSSimon Schubert 	/* If the modifiers didn't get printed by the type, print them
39875796c8dcSSimon Schubert 	   now.  */
39885796c8dcSSimon Schubert 	while (i > 0)
39895796c8dcSSimon Schubert 	  {
39905796c8dcSSimon Schubert 	    --i;
39915796c8dcSSimon Schubert 	    if (! adpm[i].printed)
39925796c8dcSSimon Schubert 	      {
39935796c8dcSSimon Schubert 		d_append_char (dpi, ' ');
3994c50c785cSJohn Marino 		d_print_mod (dpi, options, adpm[i].mod);
39955796c8dcSSimon Schubert 	      }
39965796c8dcSSimon Schubert 	  }
39975796c8dcSSimon Schubert 
39985796c8dcSSimon Schubert 	dpi->modifiers = hold_modifiers;
39995796c8dcSSimon Schubert 
40005796c8dcSSimon Schubert 	return;
40015796c8dcSSimon Schubert       }
40025796c8dcSSimon Schubert 
40035796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE:
40045796c8dcSSimon Schubert       {
40055796c8dcSSimon Schubert 	struct d_print_mod *hold_dpm;
40065796c8dcSSimon Schubert 	struct demangle_component *dcl;
40075796c8dcSSimon Schubert 
40085796c8dcSSimon Schubert 	/* Don't push modifiers into a template definition.  Doing so
40095796c8dcSSimon Schubert 	   could give the wrong definition for a template argument.
40105796c8dcSSimon Schubert 	   Instead, treat the template essentially as a name.  */
40115796c8dcSSimon Schubert 
40125796c8dcSSimon Schubert 	hold_dpm = dpi->modifiers;
40135796c8dcSSimon Schubert 	dpi->modifiers = NULL;
40145796c8dcSSimon Schubert 
40155796c8dcSSimon Schubert         dcl = d_left (dc);
40165796c8dcSSimon Schubert 
4017c50c785cSJohn Marino         if ((options & DMGL_JAVA) != 0
40185796c8dcSSimon Schubert             && dcl->type == DEMANGLE_COMPONENT_NAME
40195796c8dcSSimon Schubert             && dcl->u.s_name.len == 6
40205796c8dcSSimon Schubert             && strncmp (dcl->u.s_name.s, "JArray", 6) == 0)
40215796c8dcSSimon Schubert           {
40225796c8dcSSimon Schubert             /* Special-case Java arrays, so that JArray<TYPE> appears
40235796c8dcSSimon Schubert                instead as TYPE[].  */
40245796c8dcSSimon Schubert 
4025c50c785cSJohn Marino             d_print_comp (dpi, options, d_right (dc));
40265796c8dcSSimon Schubert             d_append_string (dpi, "[]");
40275796c8dcSSimon Schubert           }
40285796c8dcSSimon Schubert         else
40295796c8dcSSimon Schubert           {
4030c50c785cSJohn Marino 	    d_print_comp (dpi, options, dcl);
40315796c8dcSSimon Schubert 	    if (d_last_char (dpi) == '<')
40325796c8dcSSimon Schubert 	      d_append_char (dpi, ' ');
40335796c8dcSSimon Schubert 	    d_append_char (dpi, '<');
4034c50c785cSJohn Marino 	    d_print_comp (dpi, options, d_right (dc));
40355796c8dcSSimon Schubert 	    /* Avoid generating two consecutive '>' characters, to avoid
40365796c8dcSSimon Schubert 	       the C++ syntactic ambiguity.  */
40375796c8dcSSimon Schubert 	    if (d_last_char (dpi) == '>')
40385796c8dcSSimon Schubert 	      d_append_char (dpi, ' ');
40395796c8dcSSimon Schubert 	    d_append_char (dpi, '>');
40405796c8dcSSimon Schubert           }
40415796c8dcSSimon Schubert 
40425796c8dcSSimon Schubert 	dpi->modifiers = hold_dpm;
40435796c8dcSSimon Schubert 
40445796c8dcSSimon Schubert 	return;
40455796c8dcSSimon Schubert       }
40465796c8dcSSimon Schubert 
40475796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
40485796c8dcSSimon Schubert       {
40495796c8dcSSimon Schubert 	struct d_print_template *hold_dpt;
40505796c8dcSSimon Schubert 	struct demangle_component *a = d_lookup_template_argument (dpi, dc);
40515796c8dcSSimon Schubert 
40525796c8dcSSimon Schubert 	if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
40535796c8dcSSimon Schubert 	  a = d_index_template_argument (a, dpi->pack_index);
40545796c8dcSSimon Schubert 
40555796c8dcSSimon Schubert 	if (a == NULL)
40565796c8dcSSimon Schubert 	  {
40575796c8dcSSimon Schubert 	    d_print_error (dpi);
40585796c8dcSSimon Schubert 	    return;
40595796c8dcSSimon Schubert 	  }
40605796c8dcSSimon Schubert 
40615796c8dcSSimon Schubert 	/* While processing this parameter, we need to pop the list of
40625796c8dcSSimon Schubert 	   templates.  This is because the template parameter may
40635796c8dcSSimon Schubert 	   itself be a reference to a parameter of an outer
40645796c8dcSSimon Schubert 	   template.  */
40655796c8dcSSimon Schubert 
40665796c8dcSSimon Schubert 	hold_dpt = dpi->templates;
40675796c8dcSSimon Schubert 	dpi->templates = hold_dpt->next;
40685796c8dcSSimon Schubert 
4069c50c785cSJohn Marino 	d_print_comp (dpi, options, a);
40705796c8dcSSimon Schubert 
40715796c8dcSSimon Schubert 	dpi->templates = hold_dpt;
40725796c8dcSSimon Schubert 
40735796c8dcSSimon Schubert 	return;
40745796c8dcSSimon Schubert       }
40755796c8dcSSimon Schubert 
40765796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CTOR:
4077c50c785cSJohn Marino       d_print_comp (dpi, options, dc->u.s_ctor.name);
40785796c8dcSSimon Schubert       return;
40795796c8dcSSimon Schubert 
40805796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_DTOR:
40815796c8dcSSimon Schubert       d_append_char (dpi, '~');
4082c50c785cSJohn Marino       d_print_comp (dpi, options, dc->u.s_dtor.name);
40835796c8dcSSimon Schubert       return;
40845796c8dcSSimon Schubert 
40855796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VTABLE:
40865796c8dcSSimon Schubert       d_append_string (dpi, "vtable for ");
4087c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
40885796c8dcSSimon Schubert       return;
40895796c8dcSSimon Schubert 
40905796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VTT:
40915796c8dcSSimon Schubert       d_append_string (dpi, "VTT for ");
4092c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
40935796c8dcSSimon Schubert       return;
40945796c8dcSSimon Schubert 
40955796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
40965796c8dcSSimon Schubert       d_append_string (dpi, "construction vtable for ");
4097c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
40985796c8dcSSimon Schubert       d_append_string (dpi, "-in-");
4099c50c785cSJohn Marino       d_print_comp (dpi, options, d_right (dc));
41005796c8dcSSimon Schubert       return;
41015796c8dcSSimon Schubert 
41025796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPEINFO:
41035796c8dcSSimon Schubert       d_append_string (dpi, "typeinfo for ");
4104c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41055796c8dcSSimon Schubert       return;
41065796c8dcSSimon Schubert 
41075796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPEINFO_NAME:
41085796c8dcSSimon Schubert       d_append_string (dpi, "typeinfo name for ");
4109c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41105796c8dcSSimon Schubert       return;
41115796c8dcSSimon Schubert 
41125796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPEINFO_FN:
41135796c8dcSSimon Schubert       d_append_string (dpi, "typeinfo fn for ");
4114c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41155796c8dcSSimon Schubert       return;
41165796c8dcSSimon Schubert 
41175796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_THUNK:
41185796c8dcSSimon Schubert       d_append_string (dpi, "non-virtual thunk to ");
4119c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41205796c8dcSSimon Schubert       return;
41215796c8dcSSimon Schubert 
41225796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
41235796c8dcSSimon Schubert       d_append_string (dpi, "virtual thunk to ");
4124c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41255796c8dcSSimon Schubert       return;
41265796c8dcSSimon Schubert 
41275796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COVARIANT_THUNK:
41285796c8dcSSimon Schubert       d_append_string (dpi, "covariant return thunk to ");
4129c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41305796c8dcSSimon Schubert       return;
41315796c8dcSSimon Schubert 
41325796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_JAVA_CLASS:
41335796c8dcSSimon Schubert       d_append_string (dpi, "java Class for ");
4134c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41355796c8dcSSimon Schubert       return;
41365796c8dcSSimon Schubert 
41375796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_GUARD:
41385796c8dcSSimon Schubert       d_append_string (dpi, "guard variable for ");
4139c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41405796c8dcSSimon Schubert       return;
41415796c8dcSSimon Schubert 
4142*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TLS_INIT:
4143*ef5ccd6cSJohn Marino       d_append_string (dpi, "TLS init function for ");
4144*ef5ccd6cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
4145*ef5ccd6cSJohn Marino       return;
4146*ef5ccd6cSJohn Marino 
4147*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_TLS_WRAPPER:
4148*ef5ccd6cSJohn Marino       d_append_string (dpi, "TLS wrapper function for ");
4149*ef5ccd6cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
4150*ef5ccd6cSJohn Marino       return;
4151*ef5ccd6cSJohn Marino 
41525796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_REFTEMP:
4153a45ae5f8SJohn Marino       d_append_string (dpi, "reference temporary #");
4154a45ae5f8SJohn Marino       d_print_comp (dpi, options, d_right (dc));
4155a45ae5f8SJohn Marino       d_append_string (dpi, " for ");
4156c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41575796c8dcSSimon Schubert       return;
41585796c8dcSSimon Schubert 
41595796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
41605796c8dcSSimon Schubert       d_append_string (dpi, "hidden alias for ");
4161c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
41625796c8dcSSimon Schubert       return;
41635796c8dcSSimon Schubert 
4164a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
4165a45ae5f8SJohn Marino       d_append_string (dpi, "transaction clone for ");
4166a45ae5f8SJohn Marino       d_print_comp (dpi, options, d_left (dc));
4167a45ae5f8SJohn Marino       return;
4168a45ae5f8SJohn Marino 
4169a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
4170a45ae5f8SJohn Marino       d_append_string (dpi, "non-transaction clone for ");
4171a45ae5f8SJohn Marino       d_print_comp (dpi, options, d_left (dc));
4172a45ae5f8SJohn Marino       return;
4173a45ae5f8SJohn Marino 
41745796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_SUB_STD:
41755796c8dcSSimon Schubert       d_append_buffer (dpi, dc->u.s_string.string, dc->u.s_string.len);
41765796c8dcSSimon Schubert       return;
41775796c8dcSSimon Schubert 
41785796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RESTRICT:
41795796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VOLATILE:
41805796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONST:
41815796c8dcSSimon Schubert       {
41825796c8dcSSimon Schubert 	struct d_print_mod *pdpm;
41835796c8dcSSimon Schubert 
41845796c8dcSSimon Schubert 	/* When printing arrays, it's possible to have cases where the
41855796c8dcSSimon Schubert 	   same CV-qualifier gets pushed on the stack multiple times.
41865796c8dcSSimon Schubert 	   We only need to print it once.  */
41875796c8dcSSimon Schubert 
41885796c8dcSSimon Schubert 	for (pdpm = dpi->modifiers; pdpm != NULL; pdpm = pdpm->next)
41895796c8dcSSimon Schubert 	  {
41905796c8dcSSimon Schubert 	    if (! pdpm->printed)
41915796c8dcSSimon Schubert 	      {
41925796c8dcSSimon Schubert 		if (pdpm->mod->type != DEMANGLE_COMPONENT_RESTRICT
41935796c8dcSSimon Schubert 		    && pdpm->mod->type != DEMANGLE_COMPONENT_VOLATILE
41945796c8dcSSimon Schubert 		    && pdpm->mod->type != DEMANGLE_COMPONENT_CONST)
41955796c8dcSSimon Schubert 		  break;
41965796c8dcSSimon Schubert 		if (pdpm->mod->type == dc->type)
41975796c8dcSSimon Schubert 		  {
4198c50c785cSJohn Marino 		    d_print_comp (dpi, options, d_left (dc));
41995796c8dcSSimon Schubert 		    return;
42005796c8dcSSimon Schubert 		  }
42015796c8dcSSimon Schubert 	      }
42025796c8dcSSimon Schubert 	  }
42035796c8dcSSimon Schubert       }
4204a45ae5f8SJohn Marino       goto modifier;
4205a45ae5f8SJohn Marino 
4206a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_REFERENCE:
4207a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
4208a45ae5f8SJohn Marino       {
4209a45ae5f8SJohn Marino 	/* Handle reference smashing: & + && = &.  */
4210a45ae5f8SJohn Marino 	const struct demangle_component *sub = d_left (dc);
4211a45ae5f8SJohn Marino 	if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
4212a45ae5f8SJohn Marino 	  {
4213a45ae5f8SJohn Marino 	    struct demangle_component *a = d_lookup_template_argument (dpi, sub);
4214a45ae5f8SJohn Marino 	    if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
4215a45ae5f8SJohn Marino 	      a = d_index_template_argument (a, dpi->pack_index);
4216a45ae5f8SJohn Marino 
4217a45ae5f8SJohn Marino 	    if (a == NULL)
4218a45ae5f8SJohn Marino 	      {
4219a45ae5f8SJohn Marino 		d_print_error (dpi);
4220a45ae5f8SJohn Marino 		return;
4221a45ae5f8SJohn Marino 	      }
4222a45ae5f8SJohn Marino 
4223a45ae5f8SJohn Marino 	    sub = a;
4224a45ae5f8SJohn Marino 	  }
4225a45ae5f8SJohn Marino 
4226a45ae5f8SJohn Marino 	if (sub->type == DEMANGLE_COMPONENT_REFERENCE
4227a45ae5f8SJohn Marino 	    || sub->type == dc->type)
4228a45ae5f8SJohn Marino 	  dc = sub;
4229a45ae5f8SJohn Marino 	else if (sub->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE)
4230a45ae5f8SJohn Marino 	  mod_inner = d_left (sub);
4231a45ae5f8SJohn Marino       }
42325796c8dcSSimon Schubert       /* Fall through.  */
4233a45ae5f8SJohn Marino 
42345796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RESTRICT_THIS:
42355796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VOLATILE_THIS:
42365796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONST_THIS:
42375796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
42385796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_POINTER:
42395796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COMPLEX:
42405796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_IMAGINARY:
4241a45ae5f8SJohn Marino     modifier:
42425796c8dcSSimon Schubert       {
42435796c8dcSSimon Schubert 	/* We keep a list of modifiers on the stack.  */
42445796c8dcSSimon Schubert 	struct d_print_mod dpm;
42455796c8dcSSimon Schubert 
42465796c8dcSSimon Schubert 	dpm.next = dpi->modifiers;
42475796c8dcSSimon Schubert 	dpi->modifiers = &dpm;
42485796c8dcSSimon Schubert 	dpm.mod = dc;
42495796c8dcSSimon Schubert 	dpm.printed = 0;
42505796c8dcSSimon Schubert 	dpm.templates = dpi->templates;
42515796c8dcSSimon Schubert 
4252a45ae5f8SJohn Marino 	if (!mod_inner)
4253a45ae5f8SJohn Marino 	  mod_inner = d_left (dc);
4254a45ae5f8SJohn Marino 
4255a45ae5f8SJohn Marino 	d_print_comp (dpi, options, mod_inner);
42565796c8dcSSimon Schubert 
42575796c8dcSSimon Schubert 	/* If the modifier didn't get printed by the type, print it
42585796c8dcSSimon Schubert 	   now.  */
42595796c8dcSSimon Schubert 	if (! dpm.printed)
4260c50c785cSJohn Marino 	  d_print_mod (dpi, options, dc);
42615796c8dcSSimon Schubert 
42625796c8dcSSimon Schubert 	dpi->modifiers = dpm.next;
42635796c8dcSSimon Schubert 
42645796c8dcSSimon Schubert 	return;
42655796c8dcSSimon Schubert       }
42665796c8dcSSimon Schubert 
42675796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_BUILTIN_TYPE:
4268c50c785cSJohn Marino       if ((options & DMGL_JAVA) == 0)
42695796c8dcSSimon Schubert 	d_append_buffer (dpi, dc->u.s_builtin.type->name,
42705796c8dcSSimon Schubert 			 dc->u.s_builtin.type->len);
42715796c8dcSSimon Schubert       else
42725796c8dcSSimon Schubert 	d_append_buffer (dpi, dc->u.s_builtin.type->java_name,
42735796c8dcSSimon Schubert 			 dc->u.s_builtin.type->java_len);
42745796c8dcSSimon Schubert       return;
42755796c8dcSSimon Schubert 
42765796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VENDOR_TYPE:
4277c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
42785796c8dcSSimon Schubert       return;
42795796c8dcSSimon Schubert 
42805796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_FUNCTION_TYPE:
42815796c8dcSSimon Schubert       {
4282c50c785cSJohn Marino 	if ((options & DMGL_RET_POSTFIX) != 0)
4283c50c785cSJohn Marino 	  d_print_function_type (dpi,
4284c50c785cSJohn Marino 				 options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
4285c50c785cSJohn Marino 				 dc, dpi->modifiers);
42865796c8dcSSimon Schubert 
42875796c8dcSSimon Schubert 	/* Print return type if present */
4288c50c785cSJohn Marino 	if (d_left (dc) != NULL && (options & DMGL_RET_POSTFIX) != 0)
4289c50c785cSJohn Marino 	  d_print_comp (dpi, options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
4290c50c785cSJohn Marino 			d_left (dc));
4291c50c785cSJohn Marino 	else if (d_left (dc) != NULL && (options & DMGL_RET_DROP) == 0)
42925796c8dcSSimon Schubert 	  {
42935796c8dcSSimon Schubert 	    struct d_print_mod dpm;
42945796c8dcSSimon Schubert 
42955796c8dcSSimon Schubert 	    /* We must pass this type down as a modifier in order to
42965796c8dcSSimon Schubert 	       print it in the right location.  */
42975796c8dcSSimon Schubert 	    dpm.next = dpi->modifiers;
42985796c8dcSSimon Schubert 	    dpi->modifiers = &dpm;
42995796c8dcSSimon Schubert 	    dpm.mod = dc;
43005796c8dcSSimon Schubert 	    dpm.printed = 0;
43015796c8dcSSimon Schubert 	    dpm.templates = dpi->templates;
43025796c8dcSSimon Schubert 
4303c50c785cSJohn Marino 	    d_print_comp (dpi, options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
4304c50c785cSJohn Marino 			  d_left (dc));
43055796c8dcSSimon Schubert 
43065796c8dcSSimon Schubert 	    dpi->modifiers = dpm.next;
43075796c8dcSSimon Schubert 
43085796c8dcSSimon Schubert 	    if (dpm.printed)
43095796c8dcSSimon Schubert 	      return;
43105796c8dcSSimon Schubert 
43115796c8dcSSimon Schubert 	    /* In standard prefix notation, there is a space between the
43125796c8dcSSimon Schubert 	       return type and the function signature.  */
4313c50c785cSJohn Marino 	    if ((options & DMGL_RET_POSTFIX) == 0)
43145796c8dcSSimon Schubert 	      d_append_char (dpi, ' ');
43155796c8dcSSimon Schubert 	  }
43165796c8dcSSimon Schubert 
4317c50c785cSJohn Marino 	if ((options & DMGL_RET_POSTFIX) == 0)
4318c50c785cSJohn Marino 	  d_print_function_type (dpi,
4319c50c785cSJohn Marino 				 options & ~(DMGL_RET_POSTFIX | DMGL_RET_DROP),
4320c50c785cSJohn Marino 				 dc, dpi->modifiers);
43215796c8dcSSimon Schubert 
43225796c8dcSSimon Schubert 	return;
43235796c8dcSSimon Schubert       }
43245796c8dcSSimon Schubert 
43255796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_ARRAY_TYPE:
43265796c8dcSSimon Schubert       {
43275796c8dcSSimon Schubert 	struct d_print_mod *hold_modifiers;
43285796c8dcSSimon Schubert 	struct d_print_mod adpm[4];
43295796c8dcSSimon Schubert 	unsigned int i;
43305796c8dcSSimon Schubert 	struct d_print_mod *pdpm;
43315796c8dcSSimon Schubert 
43325796c8dcSSimon Schubert 	/* We must pass this type down as a modifier in order to print
43335796c8dcSSimon Schubert 	   multi-dimensional arrays correctly.  If the array itself is
43345796c8dcSSimon Schubert 	   CV-qualified, we act as though the element type were
43355796c8dcSSimon Schubert 	   CV-qualified.  We do this by copying the modifiers down
43365796c8dcSSimon Schubert 	   rather than fiddling pointers, so that we don't wind up
43375796c8dcSSimon Schubert 	   with a d_print_mod higher on the stack pointing into our
43385796c8dcSSimon Schubert 	   stack frame after we return.  */
43395796c8dcSSimon Schubert 
43405796c8dcSSimon Schubert 	hold_modifiers = dpi->modifiers;
43415796c8dcSSimon Schubert 
43425796c8dcSSimon Schubert 	adpm[0].next = hold_modifiers;
43435796c8dcSSimon Schubert 	dpi->modifiers = &adpm[0];
43445796c8dcSSimon Schubert 	adpm[0].mod = dc;
43455796c8dcSSimon Schubert 	adpm[0].printed = 0;
43465796c8dcSSimon Schubert 	adpm[0].templates = dpi->templates;
43475796c8dcSSimon Schubert 
43485796c8dcSSimon Schubert 	i = 1;
43495796c8dcSSimon Schubert 	pdpm = hold_modifiers;
43505796c8dcSSimon Schubert 	while (pdpm != NULL
43515796c8dcSSimon Schubert 	       && (pdpm->mod->type == DEMANGLE_COMPONENT_RESTRICT
43525796c8dcSSimon Schubert 		   || pdpm->mod->type == DEMANGLE_COMPONENT_VOLATILE
43535796c8dcSSimon Schubert 		   || pdpm->mod->type == DEMANGLE_COMPONENT_CONST))
43545796c8dcSSimon Schubert 	  {
43555796c8dcSSimon Schubert 	    if (! pdpm->printed)
43565796c8dcSSimon Schubert 	      {
43575796c8dcSSimon Schubert 		if (i >= sizeof adpm / sizeof adpm[0])
43585796c8dcSSimon Schubert 		  {
43595796c8dcSSimon Schubert 		    d_print_error (dpi);
43605796c8dcSSimon Schubert 		    return;
43615796c8dcSSimon Schubert 		  }
43625796c8dcSSimon Schubert 
43635796c8dcSSimon Schubert 		adpm[i] = *pdpm;
43645796c8dcSSimon Schubert 		adpm[i].next = dpi->modifiers;
43655796c8dcSSimon Schubert 		dpi->modifiers = &adpm[i];
43665796c8dcSSimon Schubert 		pdpm->printed = 1;
43675796c8dcSSimon Schubert 		++i;
43685796c8dcSSimon Schubert 	      }
43695796c8dcSSimon Schubert 
43705796c8dcSSimon Schubert 	    pdpm = pdpm->next;
43715796c8dcSSimon Schubert 	  }
43725796c8dcSSimon Schubert 
4373c50c785cSJohn Marino 	d_print_comp (dpi, options, d_right (dc));
43745796c8dcSSimon Schubert 
43755796c8dcSSimon Schubert 	dpi->modifiers = hold_modifiers;
43765796c8dcSSimon Schubert 
43775796c8dcSSimon Schubert 	if (adpm[0].printed)
43785796c8dcSSimon Schubert 	  return;
43795796c8dcSSimon Schubert 
43805796c8dcSSimon Schubert 	while (i > 1)
43815796c8dcSSimon Schubert 	  {
43825796c8dcSSimon Schubert 	    --i;
4383c50c785cSJohn Marino 	    d_print_mod (dpi, options, adpm[i].mod);
43845796c8dcSSimon Schubert 	  }
43855796c8dcSSimon Schubert 
4386c50c785cSJohn Marino 	d_print_array_type (dpi, options, dc, dpi->modifiers);
43875796c8dcSSimon Schubert 
43885796c8dcSSimon Schubert 	return;
43895796c8dcSSimon Schubert       }
43905796c8dcSSimon Schubert 
43915796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_PTRMEM_TYPE:
4392cf7f2e2dSJohn Marino     case DEMANGLE_COMPONENT_VECTOR_TYPE:
43935796c8dcSSimon Schubert       {
43945796c8dcSSimon Schubert 	struct d_print_mod dpm;
43955796c8dcSSimon Schubert 
43965796c8dcSSimon Schubert 	dpm.next = dpi->modifiers;
43975796c8dcSSimon Schubert 	dpi->modifiers = &dpm;
43985796c8dcSSimon Schubert 	dpm.mod = dc;
43995796c8dcSSimon Schubert 	dpm.printed = 0;
44005796c8dcSSimon Schubert 	dpm.templates = dpi->templates;
44015796c8dcSSimon Schubert 
4402c50c785cSJohn Marino 	d_print_comp (dpi, options, d_right (dc));
44035796c8dcSSimon Schubert 
44045796c8dcSSimon Schubert 	/* If the modifier didn't get printed by the type, print it
44055796c8dcSSimon Schubert 	   now.  */
44065796c8dcSSimon Schubert 	if (! dpm.printed)
4407c50c785cSJohn Marino 	  d_print_mod (dpi, options, dc);
44085796c8dcSSimon Schubert 
44095796c8dcSSimon Schubert 	dpi->modifiers = dpm.next;
44105796c8dcSSimon Schubert 
44115796c8dcSSimon Schubert 	return;
44125796c8dcSSimon Schubert       }
44135796c8dcSSimon Schubert 
44145796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_FIXED_TYPE:
44155796c8dcSSimon Schubert       if (dc->u.s_fixed.sat)
44165796c8dcSSimon Schubert 	d_append_string (dpi, "_Sat ");
44175796c8dcSSimon Schubert       /* Don't print "int _Accum".  */
44185796c8dcSSimon Schubert       if (dc->u.s_fixed.length->u.s_builtin.type
44195796c8dcSSimon Schubert 	  != &cplus_demangle_builtin_types['i'-'a'])
44205796c8dcSSimon Schubert 	{
4421c50c785cSJohn Marino 	  d_print_comp (dpi, options, dc->u.s_fixed.length);
44225796c8dcSSimon Schubert 	  d_append_char (dpi, ' ');
44235796c8dcSSimon Schubert 	}
44245796c8dcSSimon Schubert       if (dc->u.s_fixed.accum)
44255796c8dcSSimon Schubert 	d_append_string (dpi, "_Accum");
44265796c8dcSSimon Schubert       else
44275796c8dcSSimon Schubert 	d_append_string (dpi, "_Fract");
44285796c8dcSSimon Schubert       return;
44295796c8dcSSimon Schubert 
44305796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_ARGLIST:
44315796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
44325796c8dcSSimon Schubert       if (d_left (dc) != NULL)
4433c50c785cSJohn Marino 	d_print_comp (dpi, options, d_left (dc));
44345796c8dcSSimon Schubert       if (d_right (dc) != NULL)
44355796c8dcSSimon Schubert 	{
44365796c8dcSSimon Schubert 	  size_t len;
4437cf7f2e2dSJohn Marino 	  unsigned long int flush_count;
4438cf7f2e2dSJohn Marino 	  /* Make sure ", " isn't flushed by d_append_string, otherwise
4439cf7f2e2dSJohn Marino 	     dpi->len -= 2 wouldn't work.  */
4440cf7f2e2dSJohn Marino 	  if (dpi->len >= sizeof (dpi->buf) - 2)
4441cf7f2e2dSJohn Marino 	    d_print_flush (dpi);
44425796c8dcSSimon Schubert 	  d_append_string (dpi, ", ");
44435796c8dcSSimon Schubert 	  len = dpi->len;
4444cf7f2e2dSJohn Marino 	  flush_count = dpi->flush_count;
4445c50c785cSJohn Marino 	  d_print_comp (dpi, options, d_right (dc));
44465796c8dcSSimon Schubert 	  /* If that didn't print anything (which can happen with empty
44475796c8dcSSimon Schubert 	     template argument packs), remove the comma and space.  */
4448cf7f2e2dSJohn Marino 	  if (dpi->flush_count == flush_count && dpi->len == len)
44495796c8dcSSimon Schubert 	    dpi->len -= 2;
44505796c8dcSSimon Schubert 	}
44515796c8dcSSimon Schubert       return;
44525796c8dcSSimon Schubert 
4453*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_INITIALIZER_LIST:
4454*ef5ccd6cSJohn Marino       {
4455*ef5ccd6cSJohn Marino 	struct demangle_component *type = d_left (dc);
4456*ef5ccd6cSJohn Marino 	struct demangle_component *list = d_right (dc);
4457*ef5ccd6cSJohn Marino 
4458*ef5ccd6cSJohn Marino 	if (type)
4459*ef5ccd6cSJohn Marino 	  d_print_comp (dpi, options, type);
4460*ef5ccd6cSJohn Marino 	d_append_char (dpi, '{');
4461*ef5ccd6cSJohn Marino 	d_print_comp (dpi, options, list);
4462*ef5ccd6cSJohn Marino 	d_append_char (dpi, '}');
4463*ef5ccd6cSJohn Marino       }
4464*ef5ccd6cSJohn Marino       return;
4465*ef5ccd6cSJohn Marino 
44665796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_OPERATOR:
44675796c8dcSSimon Schubert       {
4468*ef5ccd6cSJohn Marino 	const struct demangle_operator_info *op = dc->u.s_operator.op;
4469*ef5ccd6cSJohn Marino 	int len = op->len;
44705796c8dcSSimon Schubert 
44715796c8dcSSimon Schubert 	d_append_string (dpi, "operator");
4472*ef5ccd6cSJohn Marino 	/* Add a space before new/delete.  */
4473*ef5ccd6cSJohn Marino 	if (IS_LOWER (op->name[0]))
44745796c8dcSSimon Schubert 	  d_append_char (dpi, ' ');
4475*ef5ccd6cSJohn Marino 	/* Omit a trailing space.  */
4476*ef5ccd6cSJohn Marino 	if (op->name[len-1] == ' ')
4477*ef5ccd6cSJohn Marino 	  --len;
4478*ef5ccd6cSJohn Marino 	d_append_buffer (dpi, op->name, len);
44795796c8dcSSimon Schubert 	return;
44805796c8dcSSimon Schubert       }
44815796c8dcSSimon Schubert 
44825796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
44835796c8dcSSimon Schubert       d_append_string (dpi, "operator ");
4484c50c785cSJohn Marino       d_print_comp (dpi, options, dc->u.s_extended_operator.name);
44855796c8dcSSimon Schubert       return;
44865796c8dcSSimon Schubert 
44875796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CAST:
44885796c8dcSSimon Schubert       d_append_string (dpi, "operator ");
4489c50c785cSJohn Marino       d_print_cast (dpi, options, dc);
44905796c8dcSSimon Schubert       return;
44915796c8dcSSimon Schubert 
4492*ef5ccd6cSJohn Marino     case DEMANGLE_COMPONENT_NULLARY:
4493*ef5ccd6cSJohn Marino       d_print_expr_op (dpi, options, d_left (dc));
4494*ef5ccd6cSJohn Marino       return;
4495*ef5ccd6cSJohn Marino 
44965796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_UNARY:
4497c50c785cSJohn Marino       {
4498*ef5ccd6cSJohn Marino 	struct demangle_component *op = d_left (dc);
4499*ef5ccd6cSJohn Marino 	struct demangle_component *operand = d_right (dc);
4500*ef5ccd6cSJohn Marino 	const char *code = NULL;
4501c50c785cSJohn Marino 
4502*ef5ccd6cSJohn Marino 	if (op->type == DEMANGLE_COMPONENT_OPERATOR)
4503*ef5ccd6cSJohn Marino 	  {
4504*ef5ccd6cSJohn Marino 	    code = op->u.s_operator.op->code;
4505*ef5ccd6cSJohn Marino 	    if (!strcmp (code, "ad"))
4506*ef5ccd6cSJohn Marino 	      {
4507*ef5ccd6cSJohn Marino 		/* Don't print the argument list for the address of a
4508*ef5ccd6cSJohn Marino 		   function.  */
4509*ef5ccd6cSJohn Marino 		if (operand->type == DEMANGLE_COMPONENT_TYPED_NAME
4510*ef5ccd6cSJohn Marino 		    && d_left (operand)->type == DEMANGLE_COMPONENT_QUAL_NAME
4511*ef5ccd6cSJohn Marino 		    && d_right (operand)->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
4512*ef5ccd6cSJohn Marino 		  operand = d_left (operand);
4513*ef5ccd6cSJohn Marino 	      }
4514*ef5ccd6cSJohn Marino 	    if (operand->type == DEMANGLE_COMPONENT_BINARY_ARGS)
4515*ef5ccd6cSJohn Marino 	      {
4516*ef5ccd6cSJohn Marino 		/* This indicates a suffix operator.  */
4517*ef5ccd6cSJohn Marino 		operand = d_left (operand);
4518*ef5ccd6cSJohn Marino 		d_print_subexpr (dpi, options, operand);
4519*ef5ccd6cSJohn Marino 		d_print_expr_op (dpi, options, op);
4520c50c785cSJohn Marino 		return;
4521c50c785cSJohn Marino 	      }
4522c50c785cSJohn Marino 	  }
4523*ef5ccd6cSJohn Marino 
4524*ef5ccd6cSJohn Marino 	if (op->type != DEMANGLE_COMPONENT_CAST)
4525*ef5ccd6cSJohn Marino 	  d_print_expr_op (dpi, options, op);
45265796c8dcSSimon Schubert 	else
45275796c8dcSSimon Schubert 	  {
45285796c8dcSSimon Schubert 	    d_append_char (dpi, '(');
4529*ef5ccd6cSJohn Marino 	    d_print_cast (dpi, options, op);
45305796c8dcSSimon Schubert 	    d_append_char (dpi, ')');
45315796c8dcSSimon Schubert 	  }
4532*ef5ccd6cSJohn Marino 	if (code && !strcmp (code, "gs"))
4533*ef5ccd6cSJohn Marino 	  /* Avoid parens after '::'.  */
4534*ef5ccd6cSJohn Marino 	  d_print_comp (dpi, options, operand);
4535*ef5ccd6cSJohn Marino 	else if (code && !strcmp (code, "st"))
4536*ef5ccd6cSJohn Marino 	  /* Always print parens for sizeof (type).  */
4537*ef5ccd6cSJohn Marino 	  {
4538*ef5ccd6cSJohn Marino 	    d_append_char (dpi, '(');
4539*ef5ccd6cSJohn Marino 	    d_print_comp (dpi, options, operand);
4540*ef5ccd6cSJohn Marino 	    d_append_char (dpi, ')');
4541*ef5ccd6cSJohn Marino 	  }
4542*ef5ccd6cSJohn Marino 	else
4543*ef5ccd6cSJohn Marino 	  d_print_subexpr (dpi, options, operand);
4544*ef5ccd6cSJohn Marino       }
45455796c8dcSSimon Schubert       return;
45465796c8dcSSimon Schubert 
45475796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_BINARY:
45485796c8dcSSimon Schubert       if (d_right (dc)->type != DEMANGLE_COMPONENT_BINARY_ARGS)
45495796c8dcSSimon Schubert 	{
45505796c8dcSSimon Schubert 	  d_print_error (dpi);
45515796c8dcSSimon Schubert 	  return;
45525796c8dcSSimon Schubert 	}
45535796c8dcSSimon Schubert 
4554*ef5ccd6cSJohn Marino       if (op_is_new_cast (d_left (dc)))
4555*ef5ccd6cSJohn Marino 	{
4556*ef5ccd6cSJohn Marino 	  d_print_expr_op (dpi, options, d_left (dc));
4557*ef5ccd6cSJohn Marino 	  d_append_char (dpi, '<');
4558*ef5ccd6cSJohn Marino 	  d_print_comp (dpi, options, d_left (d_right (dc)));
4559*ef5ccd6cSJohn Marino 	  d_append_string (dpi, ">(");
4560*ef5ccd6cSJohn Marino 	  d_print_comp (dpi, options, d_right (d_right (dc)));
4561*ef5ccd6cSJohn Marino 	  d_append_char (dpi, ')');
4562*ef5ccd6cSJohn Marino 	  return;
4563*ef5ccd6cSJohn Marino 	}
4564*ef5ccd6cSJohn Marino 
45655796c8dcSSimon Schubert       /* We wrap an expression which uses the greater-than operator in
45665796c8dcSSimon Schubert 	 an extra layer of parens so that it does not get confused
45675796c8dcSSimon Schubert 	 with the '>' which ends the template parameters.  */
45685796c8dcSSimon Schubert       if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
45695796c8dcSSimon Schubert 	  && d_left (dc)->u.s_operator.op->len == 1
45705796c8dcSSimon Schubert 	  && d_left (dc)->u.s_operator.op->name[0] == '>')
45715796c8dcSSimon Schubert 	d_append_char (dpi, '(');
45725796c8dcSSimon Schubert 
4573c50c785cSJohn Marino       if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") == 0
4574c50c785cSJohn Marino           && d_left (d_right (dc))->type == DEMANGLE_COMPONENT_TYPED_NAME)
4575c50c785cSJohn Marino 	{
4576c50c785cSJohn Marino 	  /* Function call used in an expression should not have printed types
4577c50c785cSJohn Marino 	     of the function arguments.  Values of the function arguments still
4578c50c785cSJohn Marino 	     get printed below.  */
4579c50c785cSJohn Marino 
4580c50c785cSJohn Marino 	  const struct demangle_component *func = d_left (d_right (dc));
4581c50c785cSJohn Marino 
4582c50c785cSJohn Marino 	  if (d_right (func)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
4583c50c785cSJohn Marino 	    d_print_error (dpi);
4584c50c785cSJohn Marino 	  d_print_subexpr (dpi, options, d_left (func));
4585c50c785cSJohn Marino 	}
4586c50c785cSJohn Marino       else
4587c50c785cSJohn Marino 	d_print_subexpr (dpi, options, d_left (d_right (dc)));
4588cf7f2e2dSJohn Marino       if (strcmp (d_left (dc)->u.s_operator.op->code, "ix") == 0)
4589cf7f2e2dSJohn Marino 	{
4590cf7f2e2dSJohn Marino 	  d_append_char (dpi, '[');
4591c50c785cSJohn Marino 	  d_print_comp (dpi, options, d_right (d_right (dc)));
4592cf7f2e2dSJohn Marino 	  d_append_char (dpi, ']');
4593cf7f2e2dSJohn Marino 	}
4594cf7f2e2dSJohn Marino       else
4595cf7f2e2dSJohn Marino 	{
45965796c8dcSSimon Schubert 	  if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0)
4597c50c785cSJohn Marino 	    d_print_expr_op (dpi, options, d_left (dc));
4598c50c785cSJohn Marino 	  d_print_subexpr (dpi, options, d_right (d_right (dc)));
4599cf7f2e2dSJohn Marino 	}
46005796c8dcSSimon Schubert 
46015796c8dcSSimon Schubert       if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
46025796c8dcSSimon Schubert 	  && d_left (dc)->u.s_operator.op->len == 1
46035796c8dcSSimon Schubert 	  && d_left (dc)->u.s_operator.op->name[0] == '>')
46045796c8dcSSimon Schubert 	d_append_char (dpi, ')');
46055796c8dcSSimon Schubert 
46065796c8dcSSimon Schubert       return;
46075796c8dcSSimon Schubert 
46085796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_BINARY_ARGS:
46095796c8dcSSimon Schubert       /* We should only see this as part of DEMANGLE_COMPONENT_BINARY.  */
46105796c8dcSSimon Schubert       d_print_error (dpi);
46115796c8dcSSimon Schubert       return;
46125796c8dcSSimon Schubert 
46135796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TRINARY:
46145796c8dcSSimon Schubert       if (d_right (dc)->type != DEMANGLE_COMPONENT_TRINARY_ARG1
46155796c8dcSSimon Schubert 	  || d_right (d_right (dc))->type != DEMANGLE_COMPONENT_TRINARY_ARG2)
46165796c8dcSSimon Schubert 	{
46175796c8dcSSimon Schubert 	  d_print_error (dpi);
46185796c8dcSSimon Schubert 	  return;
46195796c8dcSSimon Schubert 	}
4620*ef5ccd6cSJohn Marino       {
4621*ef5ccd6cSJohn Marino 	struct demangle_component *op = d_left (dc);
4622*ef5ccd6cSJohn Marino 	struct demangle_component *first = d_left (d_right (dc));
4623*ef5ccd6cSJohn Marino 	struct demangle_component *second = d_left (d_right (d_right (dc)));
4624*ef5ccd6cSJohn Marino 	struct demangle_component *third = d_right (d_right (d_right (dc)));
4625*ef5ccd6cSJohn Marino 
4626*ef5ccd6cSJohn Marino 	if (!strcmp (op->u.s_operator.op->code, "qu"))
4627*ef5ccd6cSJohn Marino 	  {
4628*ef5ccd6cSJohn Marino 	    d_print_subexpr (dpi, options, first);
4629*ef5ccd6cSJohn Marino 	    d_print_expr_op (dpi, options, op);
4630*ef5ccd6cSJohn Marino 	    d_print_subexpr (dpi, options, second);
46315796c8dcSSimon Schubert 	    d_append_string (dpi, " : ");
4632*ef5ccd6cSJohn Marino 	    d_print_subexpr (dpi, options, third);
4633*ef5ccd6cSJohn Marino 	  }
4634*ef5ccd6cSJohn Marino 	else
4635*ef5ccd6cSJohn Marino 	  {
4636*ef5ccd6cSJohn Marino 	    d_append_string (dpi, "new ");
4637*ef5ccd6cSJohn Marino 	    if (d_left (first) != NULL)
4638*ef5ccd6cSJohn Marino 	      {
4639*ef5ccd6cSJohn Marino 		d_print_subexpr (dpi, options, first);
4640*ef5ccd6cSJohn Marino 		d_append_char (dpi, ' ');
4641*ef5ccd6cSJohn Marino 	      }
4642*ef5ccd6cSJohn Marino 	    d_print_comp (dpi, options, second);
4643*ef5ccd6cSJohn Marino 	    if (third)
4644*ef5ccd6cSJohn Marino 	      d_print_subexpr (dpi, options, third);
4645*ef5ccd6cSJohn Marino 	  }
4646*ef5ccd6cSJohn Marino       }
46475796c8dcSSimon Schubert       return;
46485796c8dcSSimon Schubert 
46495796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TRINARY_ARG1:
46505796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TRINARY_ARG2:
46515796c8dcSSimon Schubert       /* We should only see these are part of DEMANGLE_COMPONENT_TRINARY.  */
46525796c8dcSSimon Schubert       d_print_error (dpi);
46535796c8dcSSimon Schubert       return;
46545796c8dcSSimon Schubert 
46555796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LITERAL:
46565796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_LITERAL_NEG:
46575796c8dcSSimon Schubert       {
46585796c8dcSSimon Schubert 	enum d_builtin_type_print tp;
46595796c8dcSSimon Schubert 
46605796c8dcSSimon Schubert 	/* For some builtin types, produce simpler output.  */
46615796c8dcSSimon Schubert 	tp = D_PRINT_DEFAULT;
46625796c8dcSSimon Schubert 	if (d_left (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)
46635796c8dcSSimon Schubert 	  {
46645796c8dcSSimon Schubert 	    tp = d_left (dc)->u.s_builtin.type->print;
46655796c8dcSSimon Schubert 	    switch (tp)
46665796c8dcSSimon Schubert 	      {
46675796c8dcSSimon Schubert 	      case D_PRINT_INT:
46685796c8dcSSimon Schubert 	      case D_PRINT_UNSIGNED:
46695796c8dcSSimon Schubert 	      case D_PRINT_LONG:
46705796c8dcSSimon Schubert 	      case D_PRINT_UNSIGNED_LONG:
46715796c8dcSSimon Schubert 	      case D_PRINT_LONG_LONG:
46725796c8dcSSimon Schubert 	      case D_PRINT_UNSIGNED_LONG_LONG:
46735796c8dcSSimon Schubert 		if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME)
46745796c8dcSSimon Schubert 		  {
46755796c8dcSSimon Schubert 		    if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
46765796c8dcSSimon Schubert 		      d_append_char (dpi, '-');
4677c50c785cSJohn Marino 		    d_print_comp (dpi, options, d_right (dc));
46785796c8dcSSimon Schubert 		    switch (tp)
46795796c8dcSSimon Schubert 		      {
46805796c8dcSSimon Schubert 		      default:
46815796c8dcSSimon Schubert 			break;
46825796c8dcSSimon Schubert 		      case D_PRINT_UNSIGNED:
46835796c8dcSSimon Schubert 			d_append_char (dpi, 'u');
46845796c8dcSSimon Schubert 			break;
46855796c8dcSSimon Schubert 		      case D_PRINT_LONG:
46865796c8dcSSimon Schubert 			d_append_char (dpi, 'l');
46875796c8dcSSimon Schubert 			break;
46885796c8dcSSimon Schubert 		      case D_PRINT_UNSIGNED_LONG:
46895796c8dcSSimon Schubert 			d_append_string (dpi, "ul");
46905796c8dcSSimon Schubert 			break;
46915796c8dcSSimon Schubert 		      case D_PRINT_LONG_LONG:
46925796c8dcSSimon Schubert 			d_append_string (dpi, "ll");
46935796c8dcSSimon Schubert 			break;
46945796c8dcSSimon Schubert 		      case D_PRINT_UNSIGNED_LONG_LONG:
46955796c8dcSSimon Schubert 			d_append_string (dpi, "ull");
46965796c8dcSSimon Schubert 			break;
46975796c8dcSSimon Schubert 		      }
46985796c8dcSSimon Schubert 		    return;
46995796c8dcSSimon Schubert 		  }
47005796c8dcSSimon Schubert 		break;
47015796c8dcSSimon Schubert 
47025796c8dcSSimon Schubert 	      case D_PRINT_BOOL:
47035796c8dcSSimon Schubert 		if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME
47045796c8dcSSimon Schubert 		    && d_right (dc)->u.s_name.len == 1
47055796c8dcSSimon Schubert 		    && dc->type == DEMANGLE_COMPONENT_LITERAL)
47065796c8dcSSimon Schubert 		  {
47075796c8dcSSimon Schubert 		    switch (d_right (dc)->u.s_name.s[0])
47085796c8dcSSimon Schubert 		      {
47095796c8dcSSimon Schubert 		      case '0':
47105796c8dcSSimon Schubert 			d_append_string (dpi, "false");
47115796c8dcSSimon Schubert 			return;
47125796c8dcSSimon Schubert 		      case '1':
47135796c8dcSSimon Schubert 			d_append_string (dpi, "true");
47145796c8dcSSimon Schubert 			return;
47155796c8dcSSimon Schubert 		      default:
47165796c8dcSSimon Schubert 			break;
47175796c8dcSSimon Schubert 		      }
47185796c8dcSSimon Schubert 		  }
47195796c8dcSSimon Schubert 		break;
47205796c8dcSSimon Schubert 
47215796c8dcSSimon Schubert 	      default:
47225796c8dcSSimon Schubert 		break;
47235796c8dcSSimon Schubert 	      }
47245796c8dcSSimon Schubert 	  }
47255796c8dcSSimon Schubert 
47265796c8dcSSimon Schubert 	d_append_char (dpi, '(');
4727c50c785cSJohn Marino 	d_print_comp (dpi, options, d_left (dc));
47285796c8dcSSimon Schubert 	d_append_char (dpi, ')');
47295796c8dcSSimon Schubert 	if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
47305796c8dcSSimon Schubert 	  d_append_char (dpi, '-');
47315796c8dcSSimon Schubert 	if (tp == D_PRINT_FLOAT)
47325796c8dcSSimon Schubert 	  d_append_char (dpi, '[');
4733c50c785cSJohn Marino 	d_print_comp (dpi, options, d_right (dc));
47345796c8dcSSimon Schubert 	if (tp == D_PRINT_FLOAT)
47355796c8dcSSimon Schubert 	  d_append_char (dpi, ']');
47365796c8dcSSimon Schubert       }
47375796c8dcSSimon Schubert       return;
47385796c8dcSSimon Schubert 
4739cf7f2e2dSJohn Marino     case DEMANGLE_COMPONENT_NUMBER:
4740cf7f2e2dSJohn Marino       d_append_num (dpi, dc->u.s_number.number);
4741cf7f2e2dSJohn Marino       return;
4742cf7f2e2dSJohn Marino 
47435796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_JAVA_RESOURCE:
47445796c8dcSSimon Schubert       d_append_string (dpi, "java resource ");
4745c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
47465796c8dcSSimon Schubert       return;
47475796c8dcSSimon Schubert 
47485796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COMPOUND_NAME:
4749c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
4750c50c785cSJohn Marino       d_print_comp (dpi, options, d_right (dc));
47515796c8dcSSimon Schubert       return;
47525796c8dcSSimon Schubert 
47535796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CHARACTER:
47545796c8dcSSimon Schubert       d_append_char (dpi, dc->u.s_character.character);
47555796c8dcSSimon Schubert       return;
47565796c8dcSSimon Schubert 
47575796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_DECLTYPE:
47585796c8dcSSimon Schubert       d_append_string (dpi, "decltype (");
4759c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (dc));
47605796c8dcSSimon Schubert       d_append_char (dpi, ')');
47615796c8dcSSimon Schubert       return;
47625796c8dcSSimon Schubert 
47635796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_PACK_EXPANSION:
47645796c8dcSSimon Schubert       {
47655796c8dcSSimon Schubert 	int len;
47665796c8dcSSimon Schubert 	int i;
47675796c8dcSSimon Schubert 	struct demangle_component *a = d_find_pack (dpi, d_left (dc));
47685796c8dcSSimon Schubert 	if (a == NULL)
47695796c8dcSSimon Schubert 	  {
47705796c8dcSSimon Schubert 	    /* d_find_pack won't find anything if the only packs involved
47715796c8dcSSimon Schubert 	       in this expansion are function parameter packs; in that
47725796c8dcSSimon Schubert 	       case, just print the pattern and "...".  */
4773c50c785cSJohn Marino 	    d_print_subexpr (dpi, options, d_left (dc));
47745796c8dcSSimon Schubert 	    d_append_string (dpi, "...");
47755796c8dcSSimon Schubert 	    return;
47765796c8dcSSimon Schubert 	  }
47775796c8dcSSimon Schubert 
47785796c8dcSSimon Schubert 	len = d_pack_length (a);
47795796c8dcSSimon Schubert 	dc = d_left (dc);
47805796c8dcSSimon Schubert 	for (i = 0; i < len; ++i)
47815796c8dcSSimon Schubert 	  {
47825796c8dcSSimon Schubert 	    dpi->pack_index = i;
4783c50c785cSJohn Marino 	    d_print_comp (dpi, options, dc);
47845796c8dcSSimon Schubert 	    if (i < len-1)
47855796c8dcSSimon Schubert 	      d_append_string (dpi, ", ");
47865796c8dcSSimon Schubert 	  }
47875796c8dcSSimon Schubert       }
47885796c8dcSSimon Schubert       return;
47895796c8dcSSimon Schubert 
47905796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_FUNCTION_PARAM:
4791a45ae5f8SJohn Marino       {
4792a45ae5f8SJohn Marino 	long num = dc->u.s_number.number;
4793a45ae5f8SJohn Marino 	if (num == 0)
4794a45ae5f8SJohn Marino 	  d_append_string (dpi, "this");
4795a45ae5f8SJohn Marino 	else
4796a45ae5f8SJohn Marino 	  {
4797cf7f2e2dSJohn Marino 	    d_append_string (dpi, "{parm#");
4798a45ae5f8SJohn Marino 	    d_append_num (dpi, num);
4799cf7f2e2dSJohn Marino 	    d_append_char (dpi, '}');
4800a45ae5f8SJohn Marino 	  }
4801a45ae5f8SJohn Marino       }
48025796c8dcSSimon Schubert       return;
48035796c8dcSSimon Schubert 
48045796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
48055796c8dcSSimon Schubert       d_append_string (dpi, "global constructors keyed to ");
4806c50c785cSJohn Marino       d_print_comp (dpi, options, dc->u.s_binary.left);
48075796c8dcSSimon Schubert       return;
48085796c8dcSSimon Schubert 
48095796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
48105796c8dcSSimon Schubert       d_append_string (dpi, "global destructors keyed to ");
4811c50c785cSJohn Marino       d_print_comp (dpi, options, dc->u.s_binary.left);
48125796c8dcSSimon Schubert       return;
48135796c8dcSSimon Schubert 
4814cf7f2e2dSJohn Marino     case DEMANGLE_COMPONENT_LAMBDA:
4815cf7f2e2dSJohn Marino       d_append_string (dpi, "{lambda(");
4816c50c785cSJohn Marino       d_print_comp (dpi, options, dc->u.s_unary_num.sub);
4817cf7f2e2dSJohn Marino       d_append_string (dpi, ")#");
4818cf7f2e2dSJohn Marino       d_append_num (dpi, dc->u.s_unary_num.num + 1);
4819cf7f2e2dSJohn Marino       d_append_char (dpi, '}');
4820cf7f2e2dSJohn Marino       return;
4821cf7f2e2dSJohn Marino 
4822cf7f2e2dSJohn Marino     case DEMANGLE_COMPONENT_UNNAMED_TYPE:
4823cf7f2e2dSJohn Marino       d_append_string (dpi, "{unnamed type#");
4824cf7f2e2dSJohn Marino       d_append_num (dpi, dc->u.s_number.number + 1);
4825cf7f2e2dSJohn Marino       d_append_char (dpi, '}');
4826cf7f2e2dSJohn Marino       return;
4827cf7f2e2dSJohn Marino 
4828a45ae5f8SJohn Marino     case DEMANGLE_COMPONENT_CLONE:
4829a45ae5f8SJohn Marino       d_print_comp (dpi, options, d_left (dc));
4830a45ae5f8SJohn Marino       d_append_string (dpi, " [clone ");
4831a45ae5f8SJohn Marino       d_print_comp (dpi, options, d_right (dc));
4832a45ae5f8SJohn Marino       d_append_char (dpi, ']');
4833a45ae5f8SJohn Marino       return;
4834a45ae5f8SJohn Marino 
48355796c8dcSSimon Schubert     default:
48365796c8dcSSimon Schubert       d_print_error (dpi);
48375796c8dcSSimon Schubert       return;
48385796c8dcSSimon Schubert     }
48395796c8dcSSimon Schubert }
48405796c8dcSSimon Schubert 
48415796c8dcSSimon Schubert /* Print a Java dentifier.  For Java we try to handle encoded extended
48425796c8dcSSimon Schubert    Unicode characters.  The C++ ABI doesn't mention Unicode encoding,
48435796c8dcSSimon Schubert    so we don't it for C++.  Characters are encoded as
48445796c8dcSSimon Schubert    __U<hex-char>+_.  */
48455796c8dcSSimon Schubert 
48465796c8dcSSimon Schubert static void
d_print_java_identifier(struct d_print_info * dpi,const char * name,int len)48475796c8dcSSimon Schubert d_print_java_identifier (struct d_print_info *dpi, const char *name, int len)
48485796c8dcSSimon Schubert {
48495796c8dcSSimon Schubert   const char *p;
48505796c8dcSSimon Schubert   const char *end;
48515796c8dcSSimon Schubert 
48525796c8dcSSimon Schubert   end = name + len;
48535796c8dcSSimon Schubert   for (p = name; p < end; ++p)
48545796c8dcSSimon Schubert     {
48555796c8dcSSimon Schubert       if (end - p > 3
48565796c8dcSSimon Schubert 	  && p[0] == '_'
48575796c8dcSSimon Schubert 	  && p[1] == '_'
48585796c8dcSSimon Schubert 	  && p[2] == 'U')
48595796c8dcSSimon Schubert 	{
48605796c8dcSSimon Schubert 	  unsigned long c;
48615796c8dcSSimon Schubert 	  const char *q;
48625796c8dcSSimon Schubert 
48635796c8dcSSimon Schubert 	  c = 0;
48645796c8dcSSimon Schubert 	  for (q = p + 3; q < end; ++q)
48655796c8dcSSimon Schubert 	    {
48665796c8dcSSimon Schubert 	      int dig;
48675796c8dcSSimon Schubert 
48685796c8dcSSimon Schubert 	      if (IS_DIGIT (*q))
48695796c8dcSSimon Schubert 		dig = *q - '0';
48705796c8dcSSimon Schubert 	      else if (*q >= 'A' && *q <= 'F')
48715796c8dcSSimon Schubert 		dig = *q - 'A' + 10;
48725796c8dcSSimon Schubert 	      else if (*q >= 'a' && *q <= 'f')
48735796c8dcSSimon Schubert 		dig = *q - 'a' + 10;
48745796c8dcSSimon Schubert 	      else
48755796c8dcSSimon Schubert 		break;
48765796c8dcSSimon Schubert 
48775796c8dcSSimon Schubert 	      c = c * 16 + dig;
48785796c8dcSSimon Schubert 	    }
48795796c8dcSSimon Schubert 	  /* If the Unicode character is larger than 256, we don't try
48805796c8dcSSimon Schubert 	     to deal with it here.  FIXME.  */
48815796c8dcSSimon Schubert 	  if (q < end && *q == '_' && c < 256)
48825796c8dcSSimon Schubert 	    {
48835796c8dcSSimon Schubert 	      d_append_char (dpi, c);
48845796c8dcSSimon Schubert 	      p = q;
48855796c8dcSSimon Schubert 	      continue;
48865796c8dcSSimon Schubert 	    }
48875796c8dcSSimon Schubert 	}
48885796c8dcSSimon Schubert 
48895796c8dcSSimon Schubert       d_append_char (dpi, *p);
48905796c8dcSSimon Schubert     }
48915796c8dcSSimon Schubert }
48925796c8dcSSimon Schubert 
48935796c8dcSSimon Schubert /* Print a list of modifiers.  SUFFIX is 1 if we are printing
48945796c8dcSSimon Schubert    qualifiers on this after printing a function.  */
48955796c8dcSSimon Schubert 
48965796c8dcSSimon Schubert static void
d_print_mod_list(struct d_print_info * dpi,int options,struct d_print_mod * mods,int suffix)4897c50c785cSJohn Marino d_print_mod_list (struct d_print_info *dpi, int options,
48985796c8dcSSimon Schubert                   struct d_print_mod *mods, int suffix)
48995796c8dcSSimon Schubert {
49005796c8dcSSimon Schubert   struct d_print_template *hold_dpt;
49015796c8dcSSimon Schubert 
49025796c8dcSSimon Schubert   if (mods == NULL || d_print_saw_error (dpi))
49035796c8dcSSimon Schubert     return;
49045796c8dcSSimon Schubert 
49055796c8dcSSimon Schubert   if (mods->printed
49065796c8dcSSimon Schubert       || (! suffix
49075796c8dcSSimon Schubert 	  && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS
49085796c8dcSSimon Schubert 	      || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS
49095796c8dcSSimon Schubert 	      || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS)))
49105796c8dcSSimon Schubert     {
4911c50c785cSJohn Marino       d_print_mod_list (dpi, options, mods->next, suffix);
49125796c8dcSSimon Schubert       return;
49135796c8dcSSimon Schubert     }
49145796c8dcSSimon Schubert 
49155796c8dcSSimon Schubert   mods->printed = 1;
49165796c8dcSSimon Schubert 
49175796c8dcSSimon Schubert   hold_dpt = dpi->templates;
49185796c8dcSSimon Schubert   dpi->templates = mods->templates;
49195796c8dcSSimon Schubert 
49205796c8dcSSimon Schubert   if (mods->mod->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
49215796c8dcSSimon Schubert     {
4922c50c785cSJohn Marino       d_print_function_type (dpi, options, mods->mod, mods->next);
49235796c8dcSSimon Schubert       dpi->templates = hold_dpt;
49245796c8dcSSimon Schubert       return;
49255796c8dcSSimon Schubert     }
49265796c8dcSSimon Schubert   else if (mods->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
49275796c8dcSSimon Schubert     {
4928c50c785cSJohn Marino       d_print_array_type (dpi, options, mods->mod, mods->next);
49295796c8dcSSimon Schubert       dpi->templates = hold_dpt;
49305796c8dcSSimon Schubert       return;
49315796c8dcSSimon Schubert     }
49325796c8dcSSimon Schubert   else if (mods->mod->type == DEMANGLE_COMPONENT_LOCAL_NAME)
49335796c8dcSSimon Schubert     {
49345796c8dcSSimon Schubert       struct d_print_mod *hold_modifiers;
49355796c8dcSSimon Schubert       struct demangle_component *dc;
49365796c8dcSSimon Schubert 
49375796c8dcSSimon Schubert       /* When this is on the modifier stack, we have pulled any
49385796c8dcSSimon Schubert 	 qualifiers off the right argument already.  Otherwise, we
49395796c8dcSSimon Schubert 	 print it as usual, but don't let the left argument see any
49405796c8dcSSimon Schubert 	 modifiers.  */
49415796c8dcSSimon Schubert 
49425796c8dcSSimon Schubert       hold_modifiers = dpi->modifiers;
49435796c8dcSSimon Schubert       dpi->modifiers = NULL;
4944c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (mods->mod));
49455796c8dcSSimon Schubert       dpi->modifiers = hold_modifiers;
49465796c8dcSSimon Schubert 
4947c50c785cSJohn Marino       if ((options & DMGL_JAVA) == 0)
49485796c8dcSSimon Schubert 	d_append_string (dpi, "::");
49495796c8dcSSimon Schubert       else
49505796c8dcSSimon Schubert 	d_append_char (dpi, '.');
49515796c8dcSSimon Schubert 
49525796c8dcSSimon Schubert       dc = d_right (mods->mod);
4953cf7f2e2dSJohn Marino 
4954cf7f2e2dSJohn Marino       if (dc->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
4955cf7f2e2dSJohn Marino 	{
4956cf7f2e2dSJohn Marino 	  d_append_string (dpi, "{default arg#");
4957cf7f2e2dSJohn Marino 	  d_append_num (dpi, dc->u.s_unary_num.num + 1);
4958cf7f2e2dSJohn Marino 	  d_append_string (dpi, "}::");
4959cf7f2e2dSJohn Marino 	  dc = dc->u.s_unary_num.sub;
4960cf7f2e2dSJohn Marino 	}
4961cf7f2e2dSJohn Marino 
49625796c8dcSSimon Schubert       while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
49635796c8dcSSimon Schubert 	     || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
49645796c8dcSSimon Schubert 	     || dc->type == DEMANGLE_COMPONENT_CONST_THIS)
49655796c8dcSSimon Schubert 	dc = d_left (dc);
49665796c8dcSSimon Schubert 
4967c50c785cSJohn Marino       d_print_comp (dpi, options, dc);
49685796c8dcSSimon Schubert 
49695796c8dcSSimon Schubert       dpi->templates = hold_dpt;
49705796c8dcSSimon Schubert       return;
49715796c8dcSSimon Schubert     }
49725796c8dcSSimon Schubert 
4973c50c785cSJohn Marino   d_print_mod (dpi, options, mods->mod);
49745796c8dcSSimon Schubert 
49755796c8dcSSimon Schubert   dpi->templates = hold_dpt;
49765796c8dcSSimon Schubert 
4977c50c785cSJohn Marino   d_print_mod_list (dpi, options, mods->next, suffix);
49785796c8dcSSimon Schubert }
49795796c8dcSSimon Schubert 
49805796c8dcSSimon Schubert /* Print a modifier.  */
49815796c8dcSSimon Schubert 
49825796c8dcSSimon Schubert static void
d_print_mod(struct d_print_info * dpi,int options,const struct demangle_component * mod)4983c50c785cSJohn Marino d_print_mod (struct d_print_info *dpi, int options,
49845796c8dcSSimon Schubert              const struct demangle_component *mod)
49855796c8dcSSimon Schubert {
49865796c8dcSSimon Schubert   switch (mod->type)
49875796c8dcSSimon Schubert     {
49885796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RESTRICT:
49895796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RESTRICT_THIS:
49905796c8dcSSimon Schubert       d_append_string (dpi, " restrict");
49915796c8dcSSimon Schubert       return;
49925796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VOLATILE:
49935796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VOLATILE_THIS:
49945796c8dcSSimon Schubert       d_append_string (dpi, " volatile");
49955796c8dcSSimon Schubert       return;
49965796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONST:
49975796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_CONST_THIS:
49985796c8dcSSimon Schubert       d_append_string (dpi, " const");
49995796c8dcSSimon Schubert       return;
50005796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
50015796c8dcSSimon Schubert       d_append_char (dpi, ' ');
5002c50c785cSJohn Marino       d_print_comp (dpi, options, d_right (mod));
50035796c8dcSSimon Schubert       return;
50045796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_POINTER:
50055796c8dcSSimon Schubert       /* There is no pointer symbol in Java.  */
5006c50c785cSJohn Marino       if ((options & DMGL_JAVA) == 0)
50075796c8dcSSimon Schubert 	d_append_char (dpi, '*');
50085796c8dcSSimon Schubert       return;
50095796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_REFERENCE:
50105796c8dcSSimon Schubert       d_append_char (dpi, '&');
50115796c8dcSSimon Schubert       return;
50125796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
50135796c8dcSSimon Schubert       d_append_string (dpi, "&&");
50145796c8dcSSimon Schubert       return;
50155796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_COMPLEX:
50165796c8dcSSimon Schubert       d_append_string (dpi, "complex ");
50175796c8dcSSimon Schubert       return;
50185796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_IMAGINARY:
50195796c8dcSSimon Schubert       d_append_string (dpi, "imaginary ");
50205796c8dcSSimon Schubert       return;
50215796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_PTRMEM_TYPE:
50225796c8dcSSimon Schubert       if (d_last_char (dpi) != '(')
50235796c8dcSSimon Schubert 	d_append_char (dpi, ' ');
5024c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (mod));
50255796c8dcSSimon Schubert       d_append_string (dpi, "::*");
50265796c8dcSSimon Schubert       return;
50275796c8dcSSimon Schubert     case DEMANGLE_COMPONENT_TYPED_NAME:
5028c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (mod));
50295796c8dcSSimon Schubert       return;
5030cf7f2e2dSJohn Marino     case DEMANGLE_COMPONENT_VECTOR_TYPE:
5031cf7f2e2dSJohn Marino       d_append_string (dpi, " __vector(");
5032c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (mod));
5033cf7f2e2dSJohn Marino       d_append_char (dpi, ')');
5034cf7f2e2dSJohn Marino       return;
5035cf7f2e2dSJohn Marino 
50365796c8dcSSimon Schubert     default:
50375796c8dcSSimon Schubert       /* Otherwise, we have something that won't go back on the
50385796c8dcSSimon Schubert 	 modifier stack, so we can just print it.  */
5039c50c785cSJohn Marino       d_print_comp (dpi, options, mod);
50405796c8dcSSimon Schubert       return;
50415796c8dcSSimon Schubert     }
50425796c8dcSSimon Schubert }
50435796c8dcSSimon Schubert 
50445796c8dcSSimon Schubert /* Print a function type, except for the return type.  */
50455796c8dcSSimon Schubert 
50465796c8dcSSimon Schubert static void
d_print_function_type(struct d_print_info * dpi,int options,const struct demangle_component * dc,struct d_print_mod * mods)5047c50c785cSJohn Marino d_print_function_type (struct d_print_info *dpi, int options,
50485796c8dcSSimon Schubert                        const struct demangle_component *dc,
50495796c8dcSSimon Schubert                        struct d_print_mod *mods)
50505796c8dcSSimon Schubert {
50515796c8dcSSimon Schubert   int need_paren;
50525796c8dcSSimon Schubert   int need_space;
50535796c8dcSSimon Schubert   struct d_print_mod *p;
50545796c8dcSSimon Schubert   struct d_print_mod *hold_modifiers;
50555796c8dcSSimon Schubert 
50565796c8dcSSimon Schubert   need_paren = 0;
50575796c8dcSSimon Schubert   need_space = 0;
50585796c8dcSSimon Schubert   for (p = mods; p != NULL; p = p->next)
50595796c8dcSSimon Schubert     {
50605796c8dcSSimon Schubert       if (p->printed)
50615796c8dcSSimon Schubert 	break;
50625796c8dcSSimon Schubert 
50635796c8dcSSimon Schubert       switch (p->mod->type)
50645796c8dcSSimon Schubert 	{
50655796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_POINTER:
50665796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_REFERENCE:
50675796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
50685796c8dcSSimon Schubert 	  need_paren = 1;
50695796c8dcSSimon Schubert 	  break;
50705796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_RESTRICT:
50715796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_VOLATILE:
50725796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_CONST:
50735796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
50745796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_COMPLEX:
50755796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_IMAGINARY:
50765796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_PTRMEM_TYPE:
50775796c8dcSSimon Schubert 	  need_space = 1;
50785796c8dcSSimon Schubert 	  need_paren = 1;
50795796c8dcSSimon Schubert 	  break;
50805796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_RESTRICT_THIS:
50815796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_VOLATILE_THIS:
50825796c8dcSSimon Schubert 	case DEMANGLE_COMPONENT_CONST_THIS:
50835796c8dcSSimon Schubert 	  break;
50845796c8dcSSimon Schubert 	default:
50855796c8dcSSimon Schubert 	  break;
50865796c8dcSSimon Schubert 	}
50875796c8dcSSimon Schubert       if (need_paren)
50885796c8dcSSimon Schubert 	break;
50895796c8dcSSimon Schubert     }
50905796c8dcSSimon Schubert 
50915796c8dcSSimon Schubert   if (need_paren)
50925796c8dcSSimon Schubert     {
50935796c8dcSSimon Schubert       if (! need_space)
50945796c8dcSSimon Schubert 	{
50955796c8dcSSimon Schubert 	  if (d_last_char (dpi) != '('
50965796c8dcSSimon Schubert 	      && d_last_char (dpi) != '*')
50975796c8dcSSimon Schubert 	    need_space = 1;
50985796c8dcSSimon Schubert 	}
50995796c8dcSSimon Schubert       if (need_space && d_last_char (dpi) != ' ')
51005796c8dcSSimon Schubert 	d_append_char (dpi, ' ');
51015796c8dcSSimon Schubert       d_append_char (dpi, '(');
51025796c8dcSSimon Schubert     }
51035796c8dcSSimon Schubert 
51045796c8dcSSimon Schubert   hold_modifiers = dpi->modifiers;
51055796c8dcSSimon Schubert   dpi->modifiers = NULL;
51065796c8dcSSimon Schubert 
5107c50c785cSJohn Marino   d_print_mod_list (dpi, options, mods, 0);
51085796c8dcSSimon Schubert 
51095796c8dcSSimon Schubert   if (need_paren)
51105796c8dcSSimon Schubert     d_append_char (dpi, ')');
51115796c8dcSSimon Schubert 
51125796c8dcSSimon Schubert   d_append_char (dpi, '(');
51135796c8dcSSimon Schubert 
51145796c8dcSSimon Schubert   if (d_right (dc) != NULL)
5115c50c785cSJohn Marino     d_print_comp (dpi, options, d_right (dc));
51165796c8dcSSimon Schubert 
51175796c8dcSSimon Schubert   d_append_char (dpi, ')');
51185796c8dcSSimon Schubert 
5119c50c785cSJohn Marino   d_print_mod_list (dpi, options, mods, 1);
51205796c8dcSSimon Schubert 
51215796c8dcSSimon Schubert   dpi->modifiers = hold_modifiers;
51225796c8dcSSimon Schubert }
51235796c8dcSSimon Schubert 
51245796c8dcSSimon Schubert /* Print an array type, except for the element type.  */
51255796c8dcSSimon Schubert 
51265796c8dcSSimon Schubert static void
d_print_array_type(struct d_print_info * dpi,int options,const struct demangle_component * dc,struct d_print_mod * mods)5127c50c785cSJohn Marino d_print_array_type (struct d_print_info *dpi, int options,
51285796c8dcSSimon Schubert                     const struct demangle_component *dc,
51295796c8dcSSimon Schubert                     struct d_print_mod *mods)
51305796c8dcSSimon Schubert {
51315796c8dcSSimon Schubert   int need_space;
51325796c8dcSSimon Schubert 
51335796c8dcSSimon Schubert   need_space = 1;
51345796c8dcSSimon Schubert   if (mods != NULL)
51355796c8dcSSimon Schubert     {
51365796c8dcSSimon Schubert       int need_paren;
51375796c8dcSSimon Schubert       struct d_print_mod *p;
51385796c8dcSSimon Schubert 
51395796c8dcSSimon Schubert       need_paren = 0;
51405796c8dcSSimon Schubert       for (p = mods; p != NULL; p = p->next)
51415796c8dcSSimon Schubert 	{
51425796c8dcSSimon Schubert 	  if (! p->printed)
51435796c8dcSSimon Schubert 	    {
51445796c8dcSSimon Schubert 	      if (p->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
51455796c8dcSSimon Schubert 		{
51465796c8dcSSimon Schubert 		  need_space = 0;
51475796c8dcSSimon Schubert 		  break;
51485796c8dcSSimon Schubert 		}
51495796c8dcSSimon Schubert 	      else
51505796c8dcSSimon Schubert 		{
51515796c8dcSSimon Schubert 		  need_paren = 1;
51525796c8dcSSimon Schubert 		  need_space = 1;
51535796c8dcSSimon Schubert 		  break;
51545796c8dcSSimon Schubert 		}
51555796c8dcSSimon Schubert 	    }
51565796c8dcSSimon Schubert 	}
51575796c8dcSSimon Schubert 
51585796c8dcSSimon Schubert       if (need_paren)
51595796c8dcSSimon Schubert 	d_append_string (dpi, " (");
51605796c8dcSSimon Schubert 
5161c50c785cSJohn Marino       d_print_mod_list (dpi, options, mods, 0);
51625796c8dcSSimon Schubert 
51635796c8dcSSimon Schubert       if (need_paren)
51645796c8dcSSimon Schubert 	d_append_char (dpi, ')');
51655796c8dcSSimon Schubert     }
51665796c8dcSSimon Schubert 
51675796c8dcSSimon Schubert   if (need_space)
51685796c8dcSSimon Schubert     d_append_char (dpi, ' ');
51695796c8dcSSimon Schubert 
51705796c8dcSSimon Schubert   d_append_char (dpi, '[');
51715796c8dcSSimon Schubert 
51725796c8dcSSimon Schubert   if (d_left (dc) != NULL)
5173c50c785cSJohn Marino     d_print_comp (dpi, options, d_left (dc));
51745796c8dcSSimon Schubert 
51755796c8dcSSimon Schubert   d_append_char (dpi, ']');
51765796c8dcSSimon Schubert }
51775796c8dcSSimon Schubert 
51785796c8dcSSimon Schubert /* Print an operator in an expression.  */
51795796c8dcSSimon Schubert 
51805796c8dcSSimon Schubert static void
d_print_expr_op(struct d_print_info * dpi,int options,const struct demangle_component * dc)5181c50c785cSJohn Marino d_print_expr_op (struct d_print_info *dpi, int options,
51825796c8dcSSimon Schubert                  const struct demangle_component *dc)
51835796c8dcSSimon Schubert {
51845796c8dcSSimon Schubert   if (dc->type == DEMANGLE_COMPONENT_OPERATOR)
51855796c8dcSSimon Schubert     d_append_buffer (dpi, dc->u.s_operator.op->name,
51865796c8dcSSimon Schubert 		     dc->u.s_operator.op->len);
51875796c8dcSSimon Schubert   else
5188c50c785cSJohn Marino     d_print_comp (dpi, options, dc);
51895796c8dcSSimon Schubert }
51905796c8dcSSimon Schubert 
51915796c8dcSSimon Schubert /* Print a cast.  */
51925796c8dcSSimon Schubert 
51935796c8dcSSimon Schubert static void
d_print_cast(struct d_print_info * dpi,int options,const struct demangle_component * dc)5194c50c785cSJohn Marino d_print_cast (struct d_print_info *dpi, int options,
51955796c8dcSSimon Schubert               const struct demangle_component *dc)
51965796c8dcSSimon Schubert {
51975796c8dcSSimon Schubert   if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE)
5198c50c785cSJohn Marino     d_print_comp (dpi, options, d_left (dc));
51995796c8dcSSimon Schubert   else
52005796c8dcSSimon Schubert     {
52015796c8dcSSimon Schubert       struct d_print_mod *hold_dpm;
52025796c8dcSSimon Schubert       struct d_print_template dpt;
52035796c8dcSSimon Schubert 
52045796c8dcSSimon Schubert       /* It appears that for a templated cast operator, we need to put
52055796c8dcSSimon Schubert 	 the template parameters in scope for the operator name, but
52065796c8dcSSimon Schubert 	 not for the parameters.  The effect is that we need to handle
52075796c8dcSSimon Schubert 	 the template printing here.  */
52085796c8dcSSimon Schubert 
52095796c8dcSSimon Schubert       hold_dpm = dpi->modifiers;
52105796c8dcSSimon Schubert       dpi->modifiers = NULL;
52115796c8dcSSimon Schubert 
52125796c8dcSSimon Schubert       dpt.next = dpi->templates;
52135796c8dcSSimon Schubert       dpi->templates = &dpt;
52145796c8dcSSimon Schubert       dpt.template_decl = d_left (dc);
52155796c8dcSSimon Schubert 
5216c50c785cSJohn Marino       d_print_comp (dpi, options, d_left (d_left (dc)));
52175796c8dcSSimon Schubert 
52185796c8dcSSimon Schubert       dpi->templates = dpt.next;
52195796c8dcSSimon Schubert 
52205796c8dcSSimon Schubert       if (d_last_char (dpi) == '<')
52215796c8dcSSimon Schubert 	d_append_char (dpi, ' ');
52225796c8dcSSimon Schubert       d_append_char (dpi, '<');
5223c50c785cSJohn Marino       d_print_comp (dpi, options, d_right (d_left (dc)));
52245796c8dcSSimon Schubert       /* Avoid generating two consecutive '>' characters, to avoid
52255796c8dcSSimon Schubert 	 the C++ syntactic ambiguity.  */
52265796c8dcSSimon Schubert       if (d_last_char (dpi) == '>')
52275796c8dcSSimon Schubert 	d_append_char (dpi, ' ');
52285796c8dcSSimon Schubert       d_append_char (dpi, '>');
52295796c8dcSSimon Schubert 
52305796c8dcSSimon Schubert       dpi->modifiers = hold_dpm;
52315796c8dcSSimon Schubert     }
52325796c8dcSSimon Schubert }
52335796c8dcSSimon Schubert 
52345796c8dcSSimon Schubert /* Initialize the information structure we use to pass around
52355796c8dcSSimon Schubert    information.  */
52365796c8dcSSimon Schubert 
52375796c8dcSSimon Schubert CP_STATIC_IF_GLIBCPP_V3
52385796c8dcSSimon Schubert void
cplus_demangle_init_info(const char * mangled,int options,size_t len,struct d_info * di)52395796c8dcSSimon Schubert cplus_demangle_init_info (const char *mangled, int options, size_t len,
52405796c8dcSSimon Schubert                           struct d_info *di)
52415796c8dcSSimon Schubert {
52425796c8dcSSimon Schubert   di->s = mangled;
52435796c8dcSSimon Schubert   di->send = mangled + len;
52445796c8dcSSimon Schubert   di->options = options;
52455796c8dcSSimon Schubert 
52465796c8dcSSimon Schubert   di->n = mangled;
52475796c8dcSSimon Schubert 
52485796c8dcSSimon Schubert   /* We can not need more components than twice the number of chars in
52495796c8dcSSimon Schubert      the mangled string.  Most components correspond directly to
52505796c8dcSSimon Schubert      chars, but the ARGLIST types are exceptions.  */
52515796c8dcSSimon Schubert   di->num_comps = 2 * len;
52525796c8dcSSimon Schubert   di->next_comp = 0;
52535796c8dcSSimon Schubert 
52545796c8dcSSimon Schubert   /* Similarly, we can not need more substitutions than there are
52555796c8dcSSimon Schubert      chars in the mangled string.  */
52565796c8dcSSimon Schubert   di->num_subs = len;
52575796c8dcSSimon Schubert   di->next_sub = 0;
52585796c8dcSSimon Schubert   di->did_subs = 0;
52595796c8dcSSimon Schubert 
52605796c8dcSSimon Schubert   di->last_name = NULL;
52615796c8dcSSimon Schubert 
52625796c8dcSSimon Schubert   di->expansion = 0;
52635796c8dcSSimon Schubert }
52645796c8dcSSimon Schubert 
52655796c8dcSSimon Schubert /* Internal implementation for the demangler.  If MANGLED is a g++ v3 ABI
52665796c8dcSSimon Schubert    mangled name, return strings in repeated callback giving the demangled
52675796c8dcSSimon Schubert    name.  OPTIONS is the usual libiberty demangler options.  On success,
52685796c8dcSSimon Schubert    this returns 1.  On failure, returns 0.  */
52695796c8dcSSimon Schubert 
52705796c8dcSSimon Schubert static int
d_demangle_callback(const char * mangled,int options,demangle_callbackref callback,void * opaque)52715796c8dcSSimon Schubert d_demangle_callback (const char *mangled, int options,
52725796c8dcSSimon Schubert                      demangle_callbackref callback, void *opaque)
52735796c8dcSSimon Schubert {
52745796c8dcSSimon Schubert   enum
52755796c8dcSSimon Schubert     {
52765796c8dcSSimon Schubert       DCT_TYPE,
52775796c8dcSSimon Schubert       DCT_MANGLED,
52785796c8dcSSimon Schubert       DCT_GLOBAL_CTORS,
52795796c8dcSSimon Schubert       DCT_GLOBAL_DTORS
52805796c8dcSSimon Schubert     }
52815796c8dcSSimon Schubert   type;
52825796c8dcSSimon Schubert   struct d_info di;
52835796c8dcSSimon Schubert   struct demangle_component *dc;
52845796c8dcSSimon Schubert   int status;
52855796c8dcSSimon Schubert 
52865796c8dcSSimon Schubert   if (mangled[0] == '_' && mangled[1] == 'Z')
52875796c8dcSSimon Schubert     type = DCT_MANGLED;
52885796c8dcSSimon Schubert   else if (strncmp (mangled, "_GLOBAL_", 8) == 0
52895796c8dcSSimon Schubert 	   && (mangled[8] == '.' || mangled[8] == '_' || mangled[8] == '$')
52905796c8dcSSimon Schubert 	   && (mangled[9] == 'D' || mangled[9] == 'I')
52915796c8dcSSimon Schubert 	   && mangled[10] == '_')
52925796c8dcSSimon Schubert     type = mangled[9] == 'I' ? DCT_GLOBAL_CTORS : DCT_GLOBAL_DTORS;
52935796c8dcSSimon Schubert   else
52945796c8dcSSimon Schubert     {
52955796c8dcSSimon Schubert       if ((options & DMGL_TYPES) == 0)
52965796c8dcSSimon Schubert 	return 0;
52975796c8dcSSimon Schubert       type = DCT_TYPE;
52985796c8dcSSimon Schubert     }
52995796c8dcSSimon Schubert 
53005796c8dcSSimon Schubert   cplus_demangle_init_info (mangled, options, strlen (mangled), &di);
53015796c8dcSSimon Schubert 
53025796c8dcSSimon Schubert   {
53035796c8dcSSimon Schubert #ifdef CP_DYNAMIC_ARRAYS
53045796c8dcSSimon Schubert     __extension__ struct demangle_component comps[di.num_comps];
53055796c8dcSSimon Schubert     __extension__ struct demangle_component *subs[di.num_subs];
53065796c8dcSSimon Schubert 
53075796c8dcSSimon Schubert     di.comps = comps;
53085796c8dcSSimon Schubert     di.subs = subs;
53095796c8dcSSimon Schubert #else
53105796c8dcSSimon Schubert     di.comps = alloca (di.num_comps * sizeof (*di.comps));
53115796c8dcSSimon Schubert     di.subs = alloca (di.num_subs * sizeof (*di.subs));
53125796c8dcSSimon Schubert #endif
53135796c8dcSSimon Schubert 
53145796c8dcSSimon Schubert     switch (type)
53155796c8dcSSimon Schubert       {
53165796c8dcSSimon Schubert       case DCT_TYPE:
53175796c8dcSSimon Schubert 	dc = cplus_demangle_type (&di);
53185796c8dcSSimon Schubert 	break;
53195796c8dcSSimon Schubert       case DCT_MANGLED:
53205796c8dcSSimon Schubert 	dc = cplus_demangle_mangled_name (&di, 1);
53215796c8dcSSimon Schubert 	break;
53225796c8dcSSimon Schubert       case DCT_GLOBAL_CTORS:
53235796c8dcSSimon Schubert       case DCT_GLOBAL_DTORS:
53245796c8dcSSimon Schubert 	d_advance (&di, 11);
53255796c8dcSSimon Schubert 	dc = d_make_comp (&di,
53265796c8dcSSimon Schubert 			  (type == DCT_GLOBAL_CTORS
53275796c8dcSSimon Schubert 			   ? DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS
53285796c8dcSSimon Schubert 			   : DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS),
5329c50c785cSJohn Marino 			  d_make_demangle_mangled_name (&di, d_str (&di)),
53305796c8dcSSimon Schubert 			  NULL);
53315796c8dcSSimon Schubert 	d_advance (&di, strlen (d_str (&di)));
53325796c8dcSSimon Schubert 	break;
53335796c8dcSSimon Schubert       }
53345796c8dcSSimon Schubert 
53355796c8dcSSimon Schubert     /* If DMGL_PARAMS is set, then if we didn't consume the entire
53365796c8dcSSimon Schubert        mangled string, then we didn't successfully demangle it.  If
53375796c8dcSSimon Schubert        DMGL_PARAMS is not set, we didn't look at the trailing
53385796c8dcSSimon Schubert        parameters.  */
53395796c8dcSSimon Schubert     if (((options & DMGL_PARAMS) != 0) && d_peek_char (&di) != '\0')
53405796c8dcSSimon Schubert       dc = NULL;
53415796c8dcSSimon Schubert 
53425796c8dcSSimon Schubert #ifdef CP_DEMANGLE_DEBUG
53435796c8dcSSimon Schubert     d_dump (dc, 0);
53445796c8dcSSimon Schubert #endif
53455796c8dcSSimon Schubert 
53465796c8dcSSimon Schubert     status = (dc != NULL)
53475796c8dcSSimon Schubert              ? cplus_demangle_print_callback (options, dc, callback, opaque)
53485796c8dcSSimon Schubert              : 0;
53495796c8dcSSimon Schubert   }
53505796c8dcSSimon Schubert 
53515796c8dcSSimon Schubert   return status;
53525796c8dcSSimon Schubert }
53535796c8dcSSimon Schubert 
53545796c8dcSSimon Schubert /* Entry point for the demangler.  If MANGLED is a g++ v3 ABI mangled
53555796c8dcSSimon Schubert    name, return a buffer allocated with malloc holding the demangled
53565796c8dcSSimon Schubert    name.  OPTIONS is the usual libiberty demangler options.  On
53575796c8dcSSimon Schubert    success, this sets *PALC to the allocated size of the returned
53585796c8dcSSimon Schubert    buffer.  On failure, this sets *PALC to 0 for a bad name, or 1 for
53595796c8dcSSimon Schubert    a memory allocation failure, and returns NULL.  */
53605796c8dcSSimon Schubert 
53615796c8dcSSimon Schubert static char *
d_demangle(const char * mangled,int options,size_t * palc)53625796c8dcSSimon Schubert d_demangle (const char *mangled, int options, size_t *palc)
53635796c8dcSSimon Schubert {
53645796c8dcSSimon Schubert   struct d_growable_string dgs;
53655796c8dcSSimon Schubert   int status;
53665796c8dcSSimon Schubert 
53675796c8dcSSimon Schubert   d_growable_string_init (&dgs, 0);
53685796c8dcSSimon Schubert 
53695796c8dcSSimon Schubert   status = d_demangle_callback (mangled, options,
53705796c8dcSSimon Schubert                                 d_growable_string_callback_adapter, &dgs);
53715796c8dcSSimon Schubert   if (status == 0)
53725796c8dcSSimon Schubert     {
53735796c8dcSSimon Schubert       free (dgs.buf);
53745796c8dcSSimon Schubert       *palc = 0;
53755796c8dcSSimon Schubert       return NULL;
53765796c8dcSSimon Schubert     }
53775796c8dcSSimon Schubert 
5378cf7f2e2dSJohn Marino   *palc = dgs.allocation_failure ? 1 : dgs.alc;
53795796c8dcSSimon Schubert   return dgs.buf;
53805796c8dcSSimon Schubert }
53815796c8dcSSimon Schubert 
53825796c8dcSSimon Schubert #if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
53835796c8dcSSimon Schubert 
53845796c8dcSSimon Schubert extern char *__cxa_demangle (const char *, char *, size_t *, int *);
53855796c8dcSSimon Schubert 
53865796c8dcSSimon Schubert /* ia64 ABI-mandated entry point in the C++ runtime library for
53875796c8dcSSimon Schubert    performing demangling.  MANGLED_NAME is a NUL-terminated character
53885796c8dcSSimon Schubert    string containing the name to be demangled.
53895796c8dcSSimon Schubert 
53905796c8dcSSimon Schubert    OUTPUT_BUFFER is a region of memory, allocated with malloc, of
53915796c8dcSSimon Schubert    *LENGTH bytes, into which the demangled name is stored.  If
53925796c8dcSSimon Schubert    OUTPUT_BUFFER is not long enough, it is expanded using realloc.
53935796c8dcSSimon Schubert    OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
53945796c8dcSSimon Schubert    is placed in a region of memory allocated with malloc.
53955796c8dcSSimon Schubert 
53965796c8dcSSimon Schubert    If LENGTH is non-NULL, the length of the buffer containing the
53975796c8dcSSimon Schubert    demangled name, is placed in *LENGTH.
53985796c8dcSSimon Schubert 
53995796c8dcSSimon Schubert    The return value is a pointer to the start of the NUL-terminated
54005796c8dcSSimon Schubert    demangled name, or NULL if the demangling fails.  The caller is
54015796c8dcSSimon Schubert    responsible for deallocating this memory using free.
54025796c8dcSSimon Schubert 
54035796c8dcSSimon Schubert    *STATUS is set to one of the following values:
54045796c8dcSSimon Schubert       0: The demangling operation succeeded.
54055796c8dcSSimon Schubert      -1: A memory allocation failure occurred.
54065796c8dcSSimon Schubert      -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
54075796c8dcSSimon Schubert      -3: One of the arguments is invalid.
54085796c8dcSSimon Schubert 
54095796c8dcSSimon Schubert    The demangling is performed using the C++ ABI mangling rules, with
54105796c8dcSSimon Schubert    GNU extensions.  */
54115796c8dcSSimon Schubert 
54125796c8dcSSimon Schubert char *
__cxa_demangle(const char * mangled_name,char * output_buffer,size_t * length,int * status)54135796c8dcSSimon Schubert __cxa_demangle (const char *mangled_name, char *output_buffer,
54145796c8dcSSimon Schubert                 size_t *length, int *status)
54155796c8dcSSimon Schubert {
54165796c8dcSSimon Schubert   char *demangled;
54175796c8dcSSimon Schubert   size_t alc;
54185796c8dcSSimon Schubert 
54195796c8dcSSimon Schubert   if (mangled_name == NULL)
54205796c8dcSSimon Schubert     {
54215796c8dcSSimon Schubert       if (status != NULL)
54225796c8dcSSimon Schubert 	*status = -3;
54235796c8dcSSimon Schubert       return NULL;
54245796c8dcSSimon Schubert     }
54255796c8dcSSimon Schubert 
54265796c8dcSSimon Schubert   if (output_buffer != NULL && length == NULL)
54275796c8dcSSimon Schubert     {
54285796c8dcSSimon Schubert       if (status != NULL)
54295796c8dcSSimon Schubert 	*status = -3;
54305796c8dcSSimon Schubert       return NULL;
54315796c8dcSSimon Schubert     }
54325796c8dcSSimon Schubert 
54335796c8dcSSimon Schubert   demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc);
54345796c8dcSSimon Schubert 
54355796c8dcSSimon Schubert   if (demangled == NULL)
54365796c8dcSSimon Schubert     {
54375796c8dcSSimon Schubert       if (status != NULL)
54385796c8dcSSimon Schubert 	{
54395796c8dcSSimon Schubert 	  if (alc == 1)
54405796c8dcSSimon Schubert 	    *status = -1;
54415796c8dcSSimon Schubert 	  else
54425796c8dcSSimon Schubert 	    *status = -2;
54435796c8dcSSimon Schubert 	}
54445796c8dcSSimon Schubert       return NULL;
54455796c8dcSSimon Schubert     }
54465796c8dcSSimon Schubert 
54475796c8dcSSimon Schubert   if (output_buffer == NULL)
54485796c8dcSSimon Schubert     {
54495796c8dcSSimon Schubert       if (length != NULL)
54505796c8dcSSimon Schubert 	*length = alc;
54515796c8dcSSimon Schubert     }
54525796c8dcSSimon Schubert   else
54535796c8dcSSimon Schubert     {
54545796c8dcSSimon Schubert       if (strlen (demangled) < *length)
54555796c8dcSSimon Schubert 	{
54565796c8dcSSimon Schubert 	  strcpy (output_buffer, demangled);
54575796c8dcSSimon Schubert 	  free (demangled);
54585796c8dcSSimon Schubert 	  demangled = output_buffer;
54595796c8dcSSimon Schubert 	}
54605796c8dcSSimon Schubert       else
54615796c8dcSSimon Schubert 	{
54625796c8dcSSimon Schubert 	  free (output_buffer);
54635796c8dcSSimon Schubert 	  *length = alc;
54645796c8dcSSimon Schubert 	}
54655796c8dcSSimon Schubert     }
54665796c8dcSSimon Schubert 
54675796c8dcSSimon Schubert   if (status != NULL)
54685796c8dcSSimon Schubert     *status = 0;
54695796c8dcSSimon Schubert 
54705796c8dcSSimon Schubert   return demangled;
54715796c8dcSSimon Schubert }
54725796c8dcSSimon Schubert 
54735796c8dcSSimon Schubert extern int __gcclibcxx_demangle_callback (const char *,
54745796c8dcSSimon Schubert                                           void (*)
54755796c8dcSSimon Schubert                                             (const char *, size_t, void *),
54765796c8dcSSimon Schubert                                           void *);
54775796c8dcSSimon Schubert 
54785796c8dcSSimon Schubert /* Alternative, allocationless entry point in the C++ runtime library
54795796c8dcSSimon Schubert    for performing demangling.  MANGLED_NAME is a NUL-terminated character
54805796c8dcSSimon Schubert    string containing the name to be demangled.
54815796c8dcSSimon Schubert 
54825796c8dcSSimon Schubert    CALLBACK is a callback function, called with demangled string
54835796c8dcSSimon Schubert    segments as demangling progresses; it is called at least once,
54845796c8dcSSimon Schubert    but may be called more than once.  OPAQUE is a generalized pointer
54855796c8dcSSimon Schubert    used as a callback argument.
54865796c8dcSSimon Schubert 
54875796c8dcSSimon Schubert    The return code is one of the following values, equivalent to
54885796c8dcSSimon Schubert    the STATUS values of __cxa_demangle() (excluding -1, since this
54895796c8dcSSimon Schubert    function performs no memory allocations):
54905796c8dcSSimon Schubert       0: The demangling operation succeeded.
54915796c8dcSSimon Schubert      -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
54925796c8dcSSimon Schubert      -3: One of the arguments is invalid.
54935796c8dcSSimon Schubert 
54945796c8dcSSimon Schubert    The demangling is performed using the C++ ABI mangling rules, with
54955796c8dcSSimon Schubert    GNU extensions.  */
54965796c8dcSSimon Schubert 
54975796c8dcSSimon Schubert int
__gcclibcxx_demangle_callback(const char * mangled_name,void (* callback)(const char *,size_t,void *),void * opaque)54985796c8dcSSimon Schubert __gcclibcxx_demangle_callback (const char *mangled_name,
54995796c8dcSSimon Schubert                                void (*callback) (const char *, size_t, void *),
55005796c8dcSSimon Schubert                                void *opaque)
55015796c8dcSSimon Schubert {
55025796c8dcSSimon Schubert   int status;
55035796c8dcSSimon Schubert 
55045796c8dcSSimon Schubert   if (mangled_name == NULL || callback == NULL)
55055796c8dcSSimon Schubert     return -3;
55065796c8dcSSimon Schubert 
55075796c8dcSSimon Schubert   status = d_demangle_callback (mangled_name, DMGL_PARAMS | DMGL_TYPES,
55085796c8dcSSimon Schubert                                 callback, opaque);
55095796c8dcSSimon Schubert   if (status == 0)
55105796c8dcSSimon Schubert     return -2;
55115796c8dcSSimon Schubert 
55125796c8dcSSimon Schubert   return 0;
55135796c8dcSSimon Schubert }
55145796c8dcSSimon Schubert 
55155796c8dcSSimon Schubert #else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
55165796c8dcSSimon Schubert 
55175796c8dcSSimon Schubert /* Entry point for libiberty demangler.  If MANGLED is a g++ v3 ABI
55185796c8dcSSimon Schubert    mangled name, return a buffer allocated with malloc holding the
55195796c8dcSSimon Schubert    demangled name.  Otherwise, return NULL.  */
55205796c8dcSSimon Schubert 
55215796c8dcSSimon Schubert char *
cplus_demangle_v3(const char * mangled,int options)55225796c8dcSSimon Schubert cplus_demangle_v3 (const char *mangled, int options)
55235796c8dcSSimon Schubert {
55245796c8dcSSimon Schubert   size_t alc;
55255796c8dcSSimon Schubert 
55265796c8dcSSimon Schubert   return d_demangle (mangled, options, &alc);
55275796c8dcSSimon Schubert }
55285796c8dcSSimon Schubert 
55295796c8dcSSimon Schubert int
cplus_demangle_v3_callback(const char * mangled,int options,demangle_callbackref callback,void * opaque)55305796c8dcSSimon Schubert cplus_demangle_v3_callback (const char *mangled, int options,
55315796c8dcSSimon Schubert                             demangle_callbackref callback, void *opaque)
55325796c8dcSSimon Schubert {
55335796c8dcSSimon Schubert   return d_demangle_callback (mangled, options, callback, opaque);
55345796c8dcSSimon Schubert }
55355796c8dcSSimon Schubert 
55365796c8dcSSimon Schubert /* Demangle a Java symbol.  Java uses a subset of the V3 ABI C++ mangling
55375796c8dcSSimon Schubert    conventions, but the output formatting is a little different.
55385796c8dcSSimon Schubert    This instructs the C++ demangler not to emit pointer characters ("*"), to
55395796c8dcSSimon Schubert    use Java's namespace separator symbol ("." instead of "::"), and to output
55405796c8dcSSimon Schubert    JArray<TYPE> as TYPE[].  */
55415796c8dcSSimon Schubert 
55425796c8dcSSimon Schubert char *
java_demangle_v3(const char * mangled)55435796c8dcSSimon Schubert java_demangle_v3 (const char *mangled)
55445796c8dcSSimon Schubert {
55455796c8dcSSimon Schubert   size_t alc;
55465796c8dcSSimon Schubert 
55475796c8dcSSimon Schubert   return d_demangle (mangled, DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX, &alc);
55485796c8dcSSimon Schubert }
55495796c8dcSSimon Schubert 
55505796c8dcSSimon Schubert int
java_demangle_v3_callback(const char * mangled,demangle_callbackref callback,void * opaque)55515796c8dcSSimon Schubert java_demangle_v3_callback (const char *mangled,
55525796c8dcSSimon Schubert                            demangle_callbackref callback, void *opaque)
55535796c8dcSSimon Schubert {
55545796c8dcSSimon Schubert   return d_demangle_callback (mangled,
55555796c8dcSSimon Schubert                               DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX,
55565796c8dcSSimon Schubert                               callback, opaque);
55575796c8dcSSimon Schubert }
55585796c8dcSSimon Schubert 
55595796c8dcSSimon Schubert #endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
55605796c8dcSSimon Schubert 
55615796c8dcSSimon Schubert #ifndef IN_GLIBCPP_V3
55625796c8dcSSimon Schubert 
55635796c8dcSSimon Schubert /* Demangle a string in order to find out whether it is a constructor
55645796c8dcSSimon Schubert    or destructor.  Return non-zero on success.  Set *CTOR_KIND and
55655796c8dcSSimon Schubert    *DTOR_KIND appropriately.  */
55665796c8dcSSimon Schubert 
55675796c8dcSSimon Schubert static int
is_ctor_or_dtor(const char * mangled,enum gnu_v3_ctor_kinds * ctor_kind,enum gnu_v3_dtor_kinds * dtor_kind)55685796c8dcSSimon Schubert is_ctor_or_dtor (const char *mangled,
55695796c8dcSSimon Schubert                  enum gnu_v3_ctor_kinds *ctor_kind,
55705796c8dcSSimon Schubert                  enum gnu_v3_dtor_kinds *dtor_kind)
55715796c8dcSSimon Schubert {
55725796c8dcSSimon Schubert   struct d_info di;
55735796c8dcSSimon Schubert   struct demangle_component *dc;
55745796c8dcSSimon Schubert   int ret;
55755796c8dcSSimon Schubert 
55765796c8dcSSimon Schubert   *ctor_kind = (enum gnu_v3_ctor_kinds) 0;
55775796c8dcSSimon Schubert   *dtor_kind = (enum gnu_v3_dtor_kinds) 0;
55785796c8dcSSimon Schubert 
55795796c8dcSSimon Schubert   cplus_demangle_init_info (mangled, DMGL_GNU_V3, strlen (mangled), &di);
55805796c8dcSSimon Schubert 
55815796c8dcSSimon Schubert   {
55825796c8dcSSimon Schubert #ifdef CP_DYNAMIC_ARRAYS
55835796c8dcSSimon Schubert     __extension__ struct demangle_component comps[di.num_comps];
55845796c8dcSSimon Schubert     __extension__ struct demangle_component *subs[di.num_subs];
55855796c8dcSSimon Schubert 
55865796c8dcSSimon Schubert     di.comps = comps;
55875796c8dcSSimon Schubert     di.subs = subs;
55885796c8dcSSimon Schubert #else
55895796c8dcSSimon Schubert     di.comps = alloca (di.num_comps * sizeof (*di.comps));
55905796c8dcSSimon Schubert     di.subs = alloca (di.num_subs * sizeof (*di.subs));
55915796c8dcSSimon Schubert #endif
55925796c8dcSSimon Schubert 
55935796c8dcSSimon Schubert     dc = cplus_demangle_mangled_name (&di, 1);
55945796c8dcSSimon Schubert 
55955796c8dcSSimon Schubert     /* Note that because we did not pass DMGL_PARAMS, we don't expect
55965796c8dcSSimon Schubert        to demangle the entire string.  */
55975796c8dcSSimon Schubert 
55985796c8dcSSimon Schubert     ret = 0;
55995796c8dcSSimon Schubert     while (dc != NULL)
56005796c8dcSSimon Schubert       {
56015796c8dcSSimon Schubert 	switch (dc->type)
56025796c8dcSSimon Schubert 	  {
56035796c8dcSSimon Schubert 	  default:
56045796c8dcSSimon Schubert 	    dc = NULL;
56055796c8dcSSimon Schubert 	    break;
56065796c8dcSSimon Schubert 	  case DEMANGLE_COMPONENT_TYPED_NAME:
56075796c8dcSSimon Schubert 	  case DEMANGLE_COMPONENT_TEMPLATE:
56085796c8dcSSimon Schubert 	  case DEMANGLE_COMPONENT_RESTRICT_THIS:
56095796c8dcSSimon Schubert 	  case DEMANGLE_COMPONENT_VOLATILE_THIS:
56105796c8dcSSimon Schubert 	  case DEMANGLE_COMPONENT_CONST_THIS:
56115796c8dcSSimon Schubert 	    dc = d_left (dc);
56125796c8dcSSimon Schubert 	    break;
56135796c8dcSSimon Schubert 	  case DEMANGLE_COMPONENT_QUAL_NAME:
56145796c8dcSSimon Schubert 	  case DEMANGLE_COMPONENT_LOCAL_NAME:
56155796c8dcSSimon Schubert 	    dc = d_right (dc);
56165796c8dcSSimon Schubert 	    break;
56175796c8dcSSimon Schubert 	  case DEMANGLE_COMPONENT_CTOR:
56185796c8dcSSimon Schubert 	    *ctor_kind = dc->u.s_ctor.kind;
56195796c8dcSSimon Schubert 	    ret = 1;
56205796c8dcSSimon Schubert 	    dc = NULL;
56215796c8dcSSimon Schubert 	    break;
56225796c8dcSSimon Schubert 	  case DEMANGLE_COMPONENT_DTOR:
56235796c8dcSSimon Schubert 	    *dtor_kind = dc->u.s_dtor.kind;
56245796c8dcSSimon Schubert 	    ret = 1;
56255796c8dcSSimon Schubert 	    dc = NULL;
56265796c8dcSSimon Schubert 	    break;
56275796c8dcSSimon Schubert 	  }
56285796c8dcSSimon Schubert       }
56295796c8dcSSimon Schubert   }
56305796c8dcSSimon Schubert 
56315796c8dcSSimon Schubert   return ret;
56325796c8dcSSimon Schubert }
56335796c8dcSSimon Schubert 
56345796c8dcSSimon Schubert /* Return whether NAME is the mangled form of a g++ V3 ABI constructor
56355796c8dcSSimon Schubert    name.  A non-zero return indicates the type of constructor.  */
56365796c8dcSSimon Schubert 
56375796c8dcSSimon Schubert enum gnu_v3_ctor_kinds
is_gnu_v3_mangled_ctor(const char * name)56385796c8dcSSimon Schubert is_gnu_v3_mangled_ctor (const char *name)
56395796c8dcSSimon Schubert {
56405796c8dcSSimon Schubert   enum gnu_v3_ctor_kinds ctor_kind;
56415796c8dcSSimon Schubert   enum gnu_v3_dtor_kinds dtor_kind;
56425796c8dcSSimon Schubert 
56435796c8dcSSimon Schubert   if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
56445796c8dcSSimon Schubert     return (enum gnu_v3_ctor_kinds) 0;
56455796c8dcSSimon Schubert   return ctor_kind;
56465796c8dcSSimon Schubert }
56475796c8dcSSimon Schubert 
56485796c8dcSSimon Schubert 
56495796c8dcSSimon Schubert /* Return whether NAME is the mangled form of a g++ V3 ABI destructor
56505796c8dcSSimon Schubert    name.  A non-zero return indicates the type of destructor.  */
56515796c8dcSSimon Schubert 
56525796c8dcSSimon Schubert enum gnu_v3_dtor_kinds
is_gnu_v3_mangled_dtor(const char * name)56535796c8dcSSimon Schubert is_gnu_v3_mangled_dtor (const char *name)
56545796c8dcSSimon Schubert {
56555796c8dcSSimon Schubert   enum gnu_v3_ctor_kinds ctor_kind;
56565796c8dcSSimon Schubert   enum gnu_v3_dtor_kinds dtor_kind;
56575796c8dcSSimon Schubert 
56585796c8dcSSimon Schubert   if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
56595796c8dcSSimon Schubert     return (enum gnu_v3_dtor_kinds) 0;
56605796c8dcSSimon Schubert   return dtor_kind;
56615796c8dcSSimon Schubert }
56625796c8dcSSimon Schubert 
56635796c8dcSSimon Schubert #endif /* IN_GLIBCPP_V3 */
56645796c8dcSSimon Schubert 
56655796c8dcSSimon Schubert #ifdef STANDALONE_DEMANGLER
56665796c8dcSSimon Schubert 
56675796c8dcSSimon Schubert #include "getopt.h"
56685796c8dcSSimon Schubert #include "dyn-string.h"
56695796c8dcSSimon Schubert 
56705796c8dcSSimon Schubert static void print_usage (FILE* fp, int exit_value);
56715796c8dcSSimon Schubert 
56725796c8dcSSimon Schubert #define IS_ALPHA(CHAR)                                                  \
56735796c8dcSSimon Schubert   (((CHAR) >= 'a' && (CHAR) <= 'z')                                     \
56745796c8dcSSimon Schubert    || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
56755796c8dcSSimon Schubert 
56765796c8dcSSimon Schubert /* Non-zero if CHAR is a character than can occur in a mangled name.  */
56775796c8dcSSimon Schubert #define is_mangled_char(CHAR)                                           \
56785796c8dcSSimon Schubert   (IS_ALPHA (CHAR) || IS_DIGIT (CHAR)                                   \
56795796c8dcSSimon Schubert    || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
56805796c8dcSSimon Schubert 
56815796c8dcSSimon Schubert /* The name of this program, as invoked.  */
56825796c8dcSSimon Schubert const char* program_name;
56835796c8dcSSimon Schubert 
56845796c8dcSSimon Schubert /* Prints usage summary to FP and then exits with EXIT_VALUE.  */
56855796c8dcSSimon Schubert 
56865796c8dcSSimon Schubert static void
print_usage(FILE * fp,int exit_value)56875796c8dcSSimon Schubert print_usage (FILE* fp, int exit_value)
56885796c8dcSSimon Schubert {
56895796c8dcSSimon Schubert   fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
56905796c8dcSSimon Schubert   fprintf (fp, "Options:\n");
56915796c8dcSSimon Schubert   fprintf (fp, "  -h,--help       Display this message.\n");
56925796c8dcSSimon Schubert   fprintf (fp, "  -p,--no-params  Don't display function parameters\n");
56935796c8dcSSimon Schubert   fprintf (fp, "  -v,--verbose    Produce verbose demanglings.\n");
56945796c8dcSSimon Schubert   fprintf (fp, "If names are provided, they are demangled.  Otherwise filters standard input.\n");
56955796c8dcSSimon Schubert 
56965796c8dcSSimon Schubert   exit (exit_value);
56975796c8dcSSimon Schubert }
56985796c8dcSSimon Schubert 
56995796c8dcSSimon Schubert /* Option specification for getopt_long.  */
57005796c8dcSSimon Schubert static const struct option long_options[] =
57015796c8dcSSimon Schubert {
57025796c8dcSSimon Schubert   { "help",	 no_argument, NULL, 'h' },
57035796c8dcSSimon Schubert   { "no-params", no_argument, NULL, 'p' },
57045796c8dcSSimon Schubert   { "verbose",   no_argument, NULL, 'v' },
57055796c8dcSSimon Schubert   { NULL,        no_argument, NULL, 0   },
57065796c8dcSSimon Schubert };
57075796c8dcSSimon Schubert 
57085796c8dcSSimon Schubert /* Main entry for a demangling filter executable.  It will demangle
57095796c8dcSSimon Schubert    its command line arguments, if any.  If none are provided, it will
57105796c8dcSSimon Schubert    filter stdin to stdout, replacing any recognized mangled C++ names
57115796c8dcSSimon Schubert    with their demangled equivalents.  */
57125796c8dcSSimon Schubert 
57135796c8dcSSimon Schubert int
main(int argc,char * argv[])57145796c8dcSSimon Schubert main (int argc, char *argv[])
57155796c8dcSSimon Schubert {
57165796c8dcSSimon Schubert   int i;
57175796c8dcSSimon Schubert   int opt_char;
57185796c8dcSSimon Schubert   int options = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES;
57195796c8dcSSimon Schubert 
57205796c8dcSSimon Schubert   /* Use the program name of this program, as invoked.  */
57215796c8dcSSimon Schubert   program_name = argv[0];
57225796c8dcSSimon Schubert 
57235796c8dcSSimon Schubert   /* Parse options.  */
57245796c8dcSSimon Schubert   do
57255796c8dcSSimon Schubert     {
57265796c8dcSSimon Schubert       opt_char = getopt_long (argc, argv, "hpv", long_options, NULL);
57275796c8dcSSimon Schubert       switch (opt_char)
57285796c8dcSSimon Schubert 	{
57295796c8dcSSimon Schubert 	case '?':  /* Unrecognized option.  */
57305796c8dcSSimon Schubert 	  print_usage (stderr, 1);
57315796c8dcSSimon Schubert 	  break;
57325796c8dcSSimon Schubert 
57335796c8dcSSimon Schubert 	case 'h':
57345796c8dcSSimon Schubert 	  print_usage (stdout, 0);
57355796c8dcSSimon Schubert 	  break;
57365796c8dcSSimon Schubert 
57375796c8dcSSimon Schubert 	case 'p':
57385796c8dcSSimon Schubert 	  options &= ~ DMGL_PARAMS;
57395796c8dcSSimon Schubert 	  break;
57405796c8dcSSimon Schubert 
57415796c8dcSSimon Schubert 	case 'v':
57425796c8dcSSimon Schubert 	  options |= DMGL_VERBOSE;
57435796c8dcSSimon Schubert 	  break;
57445796c8dcSSimon Schubert 	}
57455796c8dcSSimon Schubert     }
57465796c8dcSSimon Schubert   while (opt_char != -1);
57475796c8dcSSimon Schubert 
57485796c8dcSSimon Schubert   if (optind == argc)
57495796c8dcSSimon Schubert     /* No command line arguments were provided.  Filter stdin.  */
57505796c8dcSSimon Schubert     {
57515796c8dcSSimon Schubert       dyn_string_t mangled = dyn_string_new (3);
57525796c8dcSSimon Schubert       char *s;
57535796c8dcSSimon Schubert 
57545796c8dcSSimon Schubert       /* Read all of input.  */
57555796c8dcSSimon Schubert       while (!feof (stdin))
57565796c8dcSSimon Schubert 	{
57575796c8dcSSimon Schubert 	  char c;
57585796c8dcSSimon Schubert 
57595796c8dcSSimon Schubert 	  /* Pile characters into mangled until we hit one that can't
57605796c8dcSSimon Schubert 	     occur in a mangled name.  */
57615796c8dcSSimon Schubert 	  c = getchar ();
57625796c8dcSSimon Schubert 	  while (!feof (stdin) && is_mangled_char (c))
57635796c8dcSSimon Schubert 	    {
57645796c8dcSSimon Schubert 	      dyn_string_append_char (mangled, c);
57655796c8dcSSimon Schubert 	      if (feof (stdin))
57665796c8dcSSimon Schubert 		break;
57675796c8dcSSimon Schubert 	      c = getchar ();
57685796c8dcSSimon Schubert 	    }
57695796c8dcSSimon Schubert 
57705796c8dcSSimon Schubert 	  if (dyn_string_length (mangled) > 0)
57715796c8dcSSimon Schubert 	    {
57725796c8dcSSimon Schubert #ifdef IN_GLIBCPP_V3
57735796c8dcSSimon Schubert 	      s = __cxa_demangle (dyn_string_buf (mangled), NULL, NULL, NULL);
57745796c8dcSSimon Schubert #else
57755796c8dcSSimon Schubert 	      s = cplus_demangle_v3 (dyn_string_buf (mangled), options);
57765796c8dcSSimon Schubert #endif
57775796c8dcSSimon Schubert 
57785796c8dcSSimon Schubert 	      if (s != NULL)
57795796c8dcSSimon Schubert 		{
57805796c8dcSSimon Schubert 		  fputs (s, stdout);
57815796c8dcSSimon Schubert 		  free (s);
57825796c8dcSSimon Schubert 		}
57835796c8dcSSimon Schubert 	      else
57845796c8dcSSimon Schubert 		{
57855796c8dcSSimon Schubert 		  /* It might not have been a mangled name.  Print the
57865796c8dcSSimon Schubert 		     original text.  */
57875796c8dcSSimon Schubert 		  fputs (dyn_string_buf (mangled), stdout);
57885796c8dcSSimon Schubert 		}
57895796c8dcSSimon Schubert 
57905796c8dcSSimon Schubert 	      dyn_string_clear (mangled);
57915796c8dcSSimon Schubert 	    }
57925796c8dcSSimon Schubert 
57935796c8dcSSimon Schubert 	  /* If we haven't hit EOF yet, we've read one character that
57945796c8dcSSimon Schubert 	     can't occur in a mangled name, so print it out.  */
57955796c8dcSSimon Schubert 	  if (!feof (stdin))
57965796c8dcSSimon Schubert 	    putchar (c);
57975796c8dcSSimon Schubert 	}
57985796c8dcSSimon Schubert 
57995796c8dcSSimon Schubert       dyn_string_delete (mangled);
58005796c8dcSSimon Schubert     }
58015796c8dcSSimon Schubert   else
58025796c8dcSSimon Schubert     /* Demangle command line arguments.  */
58035796c8dcSSimon Schubert     {
58045796c8dcSSimon Schubert       /* Loop over command line arguments.  */
58055796c8dcSSimon Schubert       for (i = optind; i < argc; ++i)
58065796c8dcSSimon Schubert 	{
58075796c8dcSSimon Schubert 	  char *s;
58085796c8dcSSimon Schubert #ifdef IN_GLIBCPP_V3
58095796c8dcSSimon Schubert 	  int status;
58105796c8dcSSimon Schubert #endif
58115796c8dcSSimon Schubert 
58125796c8dcSSimon Schubert 	  /* Attempt to demangle.  */
58135796c8dcSSimon Schubert #ifdef IN_GLIBCPP_V3
58145796c8dcSSimon Schubert 	  s = __cxa_demangle (argv[i], NULL, NULL, &status);
58155796c8dcSSimon Schubert #else
58165796c8dcSSimon Schubert 	  s = cplus_demangle_v3 (argv[i], options);
58175796c8dcSSimon Schubert #endif
58185796c8dcSSimon Schubert 
58195796c8dcSSimon Schubert 	  /* If it worked, print the demangled name.  */
58205796c8dcSSimon Schubert 	  if (s != NULL)
58215796c8dcSSimon Schubert 	    {
58225796c8dcSSimon Schubert 	      printf ("%s\n", s);
58235796c8dcSSimon Schubert 	      free (s);
58245796c8dcSSimon Schubert 	    }
58255796c8dcSSimon Schubert 	  else
58265796c8dcSSimon Schubert 	    {
58275796c8dcSSimon Schubert #ifdef IN_GLIBCPP_V3
58285796c8dcSSimon Schubert 	      fprintf (stderr, "Failed: %s (status %d)\n", argv[i], status);
58295796c8dcSSimon Schubert #else
58305796c8dcSSimon Schubert 	      fprintf (stderr, "Failed: %s\n", argv[i]);
58315796c8dcSSimon Schubert #endif
58325796c8dcSSimon Schubert 	    }
58335796c8dcSSimon Schubert 	}
58345796c8dcSSimon Schubert     }
58355796c8dcSSimon Schubert 
58365796c8dcSSimon Schubert   return 0;
58375796c8dcSSimon Schubert }
58385796c8dcSSimon Schubert 
58395796c8dcSSimon Schubert #endif /* STANDALONE_DEMANGLER */
5840