15796c8dcSSimon Schubert /* YACC parser for C++ names, for GDB.
25796c8dcSSimon Schubert
3*ef5ccd6cSJohn Marino Copyright (C) 2003-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert Parts of the lexer are based on c-exp.y from GDB.
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This file is part of GDB.
85796c8dcSSimon Schubert
95796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert (at your option) any later version.
135796c8dcSSimon Schubert
145796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
175796c8dcSSimon Schubert GNU General Public License for more details.
185796c8dcSSimon Schubert
195796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
215796c8dcSSimon Schubert
225796c8dcSSimon Schubert /* Note that malloc's and realloc's in this file are transformed to
235796c8dcSSimon Schubert xmalloc and xrealloc respectively by the same sed command in the
245796c8dcSSimon Schubert makefile that remaps any other malloc/realloc inserted by the parser
255796c8dcSSimon Schubert generator. Doing this with #defines and trying to control the interaction
265796c8dcSSimon Schubert with include files (<malloc.h> and <stdlib.h> for example) just became
275796c8dcSSimon Schubert too messy, particularly when such includes can be inserted at random
285796c8dcSSimon Schubert times by the parser generator. */
295796c8dcSSimon Schubert
305796c8dcSSimon Schubert %{
315796c8dcSSimon Schubert
325796c8dcSSimon Schubert #include "defs.h"
335796c8dcSSimon Schubert
345796c8dcSSimon Schubert #include <stdio.h>
355796c8dcSSimon Schubert #include <stdlib.h>
365796c8dcSSimon Schubert #include <unistd.h>
375796c8dcSSimon Schubert #include <string.h>
385796c8dcSSimon Schubert
395796c8dcSSimon Schubert #include "safe-ctype.h"
405796c8dcSSimon Schubert #include "libiberty.h"
415796c8dcSSimon Schubert #include "demangle.h"
425796c8dcSSimon Schubert #include "cp-support.h"
43a45ae5f8SJohn Marino #include "gdb_assert.h"
445796c8dcSSimon Schubert
455796c8dcSSimon Schubert /* Bison does not make it easy to create a parser without global
465796c8dcSSimon Schubert state, unfortunately. Here are all the global variables used
475796c8dcSSimon Schubert in this parser. */
485796c8dcSSimon Schubert
495796c8dcSSimon Schubert /* LEXPTR is the current pointer into our lex buffer. PREV_LEXPTR
505796c8dcSSimon Schubert is the start of the last token lexed, only used for diagnostics.
515796c8dcSSimon Schubert ERROR_LEXPTR is the first place an error occurred. GLOBAL_ERRMSG
525796c8dcSSimon Schubert is the first error message encountered. */
535796c8dcSSimon Schubert
545796c8dcSSimon Schubert static const char *lexptr, *prev_lexptr, *error_lexptr, *global_errmsg;
555796c8dcSSimon Schubert
565796c8dcSSimon Schubert /* The components built by the parser are allocated ahead of time,
575796c8dcSSimon Schubert and cached in this structure. */
585796c8dcSSimon Schubert
595796c8dcSSimon Schubert #define ALLOC_CHUNK 100
605796c8dcSSimon Schubert
615796c8dcSSimon Schubert struct demangle_info {
625796c8dcSSimon Schubert int used;
63a45ae5f8SJohn Marino struct demangle_info *next;
645796c8dcSSimon Schubert struct demangle_component comps[ALLOC_CHUNK];
655796c8dcSSimon Schubert };
665796c8dcSSimon Schubert
675796c8dcSSimon Schubert static struct demangle_info *demangle_info;
685796c8dcSSimon Schubert
695796c8dcSSimon Schubert static struct demangle_component *
d_grab(void)705796c8dcSSimon Schubert d_grab (void)
715796c8dcSSimon Schubert {
725796c8dcSSimon Schubert struct demangle_info *more;
735796c8dcSSimon Schubert
745796c8dcSSimon Schubert if (demangle_info->used >= ALLOC_CHUNK)
755796c8dcSSimon Schubert {
765796c8dcSSimon Schubert if (demangle_info->next == NULL)
775796c8dcSSimon Schubert {
785796c8dcSSimon Schubert more = malloc (sizeof (struct demangle_info));
795796c8dcSSimon Schubert more->next = NULL;
805796c8dcSSimon Schubert demangle_info->next = more;
815796c8dcSSimon Schubert }
825796c8dcSSimon Schubert else
835796c8dcSSimon Schubert more = demangle_info->next;
845796c8dcSSimon Schubert
855796c8dcSSimon Schubert more->used = 0;
865796c8dcSSimon Schubert demangle_info = more;
875796c8dcSSimon Schubert }
885796c8dcSSimon Schubert return &demangle_info->comps[demangle_info->used++];
895796c8dcSSimon Schubert }
905796c8dcSSimon Schubert
915796c8dcSSimon Schubert /* The parse tree created by the parser is stored here after a successful
925796c8dcSSimon Schubert parse. */
935796c8dcSSimon Schubert
945796c8dcSSimon Schubert static struct demangle_component *global_result;
955796c8dcSSimon Schubert
965796c8dcSSimon Schubert /* Prototypes for helper functions used when constructing the parse
975796c8dcSSimon Schubert tree. */
985796c8dcSSimon Schubert
995796c8dcSSimon Schubert static struct demangle_component *d_qualify (struct demangle_component *, int,
1005796c8dcSSimon Schubert int);
1015796c8dcSSimon Schubert
1025796c8dcSSimon Schubert static struct demangle_component *d_int_type (int);
1035796c8dcSSimon Schubert
1045796c8dcSSimon Schubert static struct demangle_component *d_unary (const char *,
1055796c8dcSSimon Schubert struct demangle_component *);
1065796c8dcSSimon Schubert static struct demangle_component *d_binary (const char *,
1075796c8dcSSimon Schubert struct demangle_component *,
1085796c8dcSSimon Schubert struct demangle_component *);
1095796c8dcSSimon Schubert
1105796c8dcSSimon Schubert /* Flags passed to d_qualify. */
1115796c8dcSSimon Schubert
1125796c8dcSSimon Schubert #define QUAL_CONST 1
1135796c8dcSSimon Schubert #define QUAL_RESTRICT 2
1145796c8dcSSimon Schubert #define QUAL_VOLATILE 4
1155796c8dcSSimon Schubert
1165796c8dcSSimon Schubert /* Flags passed to d_int_type. */
1175796c8dcSSimon Schubert
1185796c8dcSSimon Schubert #define INT_CHAR (1 << 0)
1195796c8dcSSimon Schubert #define INT_SHORT (1 << 1)
1205796c8dcSSimon Schubert #define INT_LONG (1 << 2)
1215796c8dcSSimon Schubert #define INT_LLONG (1 << 3)
1225796c8dcSSimon Schubert
1235796c8dcSSimon Schubert #define INT_SIGNED (1 << 4)
1245796c8dcSSimon Schubert #define INT_UNSIGNED (1 << 5)
1255796c8dcSSimon Schubert
1265796c8dcSSimon Schubert /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
1275796c8dcSSimon Schubert as well as gratuitiously global symbol names, so we can have multiple
1285796c8dcSSimon Schubert yacc generated parsers in gdb. Note that these are only the variables
1295796c8dcSSimon Schubert produced by yacc. If other parser generators (bison, byacc, etc) produce
1305796c8dcSSimon Schubert additional global names that conflict at link time, then those parser
1315796c8dcSSimon Schubert generators need to be fixed instead of adding those names to this list. */
1325796c8dcSSimon Schubert
1335796c8dcSSimon Schubert #define yymaxdepth cpname_maxdepth
1345796c8dcSSimon Schubert #define yyparse cpname_parse
1355796c8dcSSimon Schubert #define yylex cpname_lex
1365796c8dcSSimon Schubert #define yyerror cpname_error
1375796c8dcSSimon Schubert #define yylval cpname_lval
1385796c8dcSSimon Schubert #define yychar cpname_char
1395796c8dcSSimon Schubert #define yydebug cpname_debug
1405796c8dcSSimon Schubert #define yypact cpname_pact
1415796c8dcSSimon Schubert #define yyr1 cpname_r1
1425796c8dcSSimon Schubert #define yyr2 cpname_r2
1435796c8dcSSimon Schubert #define yydef cpname_def
1445796c8dcSSimon Schubert #define yychk cpname_chk
1455796c8dcSSimon Schubert #define yypgo cpname_pgo
1465796c8dcSSimon Schubert #define yyact cpname_act
1475796c8dcSSimon Schubert #define yyexca cpname_exca
1485796c8dcSSimon Schubert #define yyerrflag cpname_errflag
1495796c8dcSSimon Schubert #define yynerrs cpname_nerrs
1505796c8dcSSimon Schubert #define yyps cpname_ps
1515796c8dcSSimon Schubert #define yypv cpname_pv
1525796c8dcSSimon Schubert #define yys cpname_s
1535796c8dcSSimon Schubert #define yy_yys cpname_yys
1545796c8dcSSimon Schubert #define yystate cpname_state
1555796c8dcSSimon Schubert #define yytmp cpname_tmp
1565796c8dcSSimon Schubert #define yyv cpname_v
1575796c8dcSSimon Schubert #define yy_yyv cpname_yyv
1585796c8dcSSimon Schubert #define yyval cpname_val
1595796c8dcSSimon Schubert #define yylloc cpname_lloc
1605796c8dcSSimon Schubert #define yyreds cpname_reds /* With YYDEBUG defined */
1615796c8dcSSimon Schubert #define yytoks cpname_toks /* With YYDEBUG defined */
1625796c8dcSSimon Schubert #define yyname cpname_name /* With YYDEBUG defined */
1635796c8dcSSimon Schubert #define yyrule cpname_rule /* With YYDEBUG defined */
1645796c8dcSSimon Schubert #define yylhs cpname_yylhs
1655796c8dcSSimon Schubert #define yylen cpname_yylen
1665796c8dcSSimon Schubert #define yydefred cpname_yydefred
1675796c8dcSSimon Schubert #define yydgoto cpname_yydgoto
1685796c8dcSSimon Schubert #define yysindex cpname_yysindex
1695796c8dcSSimon Schubert #define yyrindex cpname_yyrindex
1705796c8dcSSimon Schubert #define yygindex cpname_yygindex
1715796c8dcSSimon Schubert #define yytable cpname_yytable
1725796c8dcSSimon Schubert #define yycheck cpname_yycheck
173*ef5ccd6cSJohn Marino #define yyss cpname_yyss
174*ef5ccd6cSJohn Marino #define yysslim cpname_yysslim
175*ef5ccd6cSJohn Marino #define yyssp cpname_yyssp
176*ef5ccd6cSJohn Marino #define yystacksize cpname_yystacksize
177*ef5ccd6cSJohn Marino #define yyvs cpname_yyvs
178*ef5ccd6cSJohn Marino #define yyvsp cpname_yyvsp
1795796c8dcSSimon Schubert
1805796c8dcSSimon Schubert int yyparse (void);
1815796c8dcSSimon Schubert static int yylex (void);
1825796c8dcSSimon Schubert static void yyerror (char *);
1835796c8dcSSimon Schubert
1845796c8dcSSimon Schubert /* Enable yydebug for the stand-alone parser. */
1855796c8dcSSimon Schubert #ifdef TEST_CPNAMES
1865796c8dcSSimon Schubert # define YYDEBUG 1
1875796c8dcSSimon Schubert #endif
1885796c8dcSSimon Schubert
1895796c8dcSSimon Schubert /* Helper functions. These wrap the demangler tree interface, handle
1905796c8dcSSimon Schubert allocation from our global store, and return the allocated component. */
1915796c8dcSSimon Schubert
1925796c8dcSSimon Schubert static struct demangle_component *
fill_comp(enum demangle_component_type d_type,struct demangle_component * lhs,struct demangle_component * rhs)1935796c8dcSSimon Schubert fill_comp (enum demangle_component_type d_type, struct demangle_component *lhs,
1945796c8dcSSimon Schubert struct demangle_component *rhs)
1955796c8dcSSimon Schubert {
1965796c8dcSSimon Schubert struct demangle_component *ret = d_grab ();
197*ef5ccd6cSJohn Marino int i;
198*ef5ccd6cSJohn Marino
199*ef5ccd6cSJohn Marino i = cplus_demangle_fill_component (ret, d_type, lhs, rhs);
200*ef5ccd6cSJohn Marino gdb_assert (i);
201*ef5ccd6cSJohn Marino
2025796c8dcSSimon Schubert return ret;
2035796c8dcSSimon Schubert }
2045796c8dcSSimon Schubert
2055796c8dcSSimon Schubert static struct demangle_component *
make_empty(enum demangle_component_type d_type)2065796c8dcSSimon Schubert make_empty (enum demangle_component_type d_type)
2075796c8dcSSimon Schubert {
2085796c8dcSSimon Schubert struct demangle_component *ret = d_grab ();
2095796c8dcSSimon Schubert ret->type = d_type;
2105796c8dcSSimon Schubert return ret;
2115796c8dcSSimon Schubert }
2125796c8dcSSimon Schubert
2135796c8dcSSimon Schubert static struct demangle_component *
make_operator(const char * name,int args)2145796c8dcSSimon Schubert make_operator (const char *name, int args)
2155796c8dcSSimon Schubert {
2165796c8dcSSimon Schubert struct demangle_component *ret = d_grab ();
217*ef5ccd6cSJohn Marino int i;
218*ef5ccd6cSJohn Marino
219*ef5ccd6cSJohn Marino i = cplus_demangle_fill_operator (ret, name, args);
220*ef5ccd6cSJohn Marino gdb_assert (i);
221*ef5ccd6cSJohn Marino
2225796c8dcSSimon Schubert return ret;
2235796c8dcSSimon Schubert }
2245796c8dcSSimon Schubert
2255796c8dcSSimon Schubert static struct demangle_component *
make_dtor(enum gnu_v3_dtor_kinds kind,struct demangle_component * name)2265796c8dcSSimon Schubert make_dtor (enum gnu_v3_dtor_kinds kind, struct demangle_component *name)
2275796c8dcSSimon Schubert {
2285796c8dcSSimon Schubert struct demangle_component *ret = d_grab ();
229*ef5ccd6cSJohn Marino int i;
230*ef5ccd6cSJohn Marino
231*ef5ccd6cSJohn Marino i = cplus_demangle_fill_dtor (ret, kind, name);
232*ef5ccd6cSJohn Marino gdb_assert (i);
233*ef5ccd6cSJohn Marino
2345796c8dcSSimon Schubert return ret;
2355796c8dcSSimon Schubert }
2365796c8dcSSimon Schubert
2375796c8dcSSimon Schubert static struct demangle_component *
make_builtin_type(const char * name)2385796c8dcSSimon Schubert make_builtin_type (const char *name)
2395796c8dcSSimon Schubert {
2405796c8dcSSimon Schubert struct demangle_component *ret = d_grab ();
241*ef5ccd6cSJohn Marino int i;
242*ef5ccd6cSJohn Marino
243*ef5ccd6cSJohn Marino i = cplus_demangle_fill_builtin_type (ret, name);
244*ef5ccd6cSJohn Marino gdb_assert (i);
245*ef5ccd6cSJohn Marino
2465796c8dcSSimon Schubert return ret;
2475796c8dcSSimon Schubert }
2485796c8dcSSimon Schubert
2495796c8dcSSimon Schubert static struct demangle_component *
make_name(const char * name,int len)2505796c8dcSSimon Schubert make_name (const char *name, int len)
2515796c8dcSSimon Schubert {
2525796c8dcSSimon Schubert struct demangle_component *ret = d_grab ();
253*ef5ccd6cSJohn Marino int i;
254*ef5ccd6cSJohn Marino
255*ef5ccd6cSJohn Marino i = cplus_demangle_fill_name (ret, name, len);
256*ef5ccd6cSJohn Marino gdb_assert (i);
257*ef5ccd6cSJohn Marino
2585796c8dcSSimon Schubert return ret;
2595796c8dcSSimon Schubert }
2605796c8dcSSimon Schubert
2615796c8dcSSimon Schubert #define d_left(dc) (dc)->u.s_binary.left
2625796c8dcSSimon Schubert #define d_right(dc) (dc)->u.s_binary.right
2635796c8dcSSimon Schubert
2645796c8dcSSimon Schubert %}
2655796c8dcSSimon Schubert
2665796c8dcSSimon Schubert %union
2675796c8dcSSimon Schubert {
2685796c8dcSSimon Schubert struct demangle_component *comp;
2695796c8dcSSimon Schubert struct nested {
2705796c8dcSSimon Schubert struct demangle_component *comp;
2715796c8dcSSimon Schubert struct demangle_component **last;
2725796c8dcSSimon Schubert } nested;
2735796c8dcSSimon Schubert struct {
2745796c8dcSSimon Schubert struct demangle_component *comp, *last;
2755796c8dcSSimon Schubert } nested1;
2765796c8dcSSimon Schubert struct {
2775796c8dcSSimon Schubert struct demangle_component *comp, **last;
2785796c8dcSSimon Schubert struct nested fn;
2795796c8dcSSimon Schubert struct demangle_component *start;
2805796c8dcSSimon Schubert int fold_flag;
2815796c8dcSSimon Schubert } abstract;
2825796c8dcSSimon Schubert int lval;
2835796c8dcSSimon Schubert const char *opname;
2845796c8dcSSimon Schubert }
2855796c8dcSSimon Schubert
2865796c8dcSSimon Schubert %type <comp> exp exp1 type start start_opt operator colon_name
2875796c8dcSSimon Schubert %type <comp> unqualified_name colon_ext_name
2885796c8dcSSimon Schubert %type <comp> template template_arg
2895796c8dcSSimon Schubert %type <comp> builtin_type
2905796c8dcSSimon Schubert %type <comp> typespec_2 array_indicator
2915796c8dcSSimon Schubert %type <comp> colon_ext_only ext_only_name
2925796c8dcSSimon Schubert
2935796c8dcSSimon Schubert %type <comp> demangler_special function conversion_op
2945796c8dcSSimon Schubert %type <nested> conversion_op_name
2955796c8dcSSimon Schubert
2965796c8dcSSimon Schubert %type <abstract> abstract_declarator direct_abstract_declarator
2975796c8dcSSimon Schubert %type <abstract> abstract_declarator_fn
2985796c8dcSSimon Schubert %type <nested> declarator direct_declarator function_arglist
2995796c8dcSSimon Schubert
3005796c8dcSSimon Schubert %type <nested> declarator_1 direct_declarator_1
3015796c8dcSSimon Schubert
3025796c8dcSSimon Schubert %type <nested> template_params function_args
3035796c8dcSSimon Schubert %type <nested> ptr_operator
3045796c8dcSSimon Schubert
3055796c8dcSSimon Schubert %type <nested1> nested_name
3065796c8dcSSimon Schubert
3075796c8dcSSimon Schubert %type <lval> qualifier qualifiers qualifiers_opt
3085796c8dcSSimon Schubert
3095796c8dcSSimon Schubert %type <lval> int_part int_seq
3105796c8dcSSimon Schubert
3115796c8dcSSimon Schubert %token <comp> INT
3125796c8dcSSimon Schubert %token <comp> FLOAT
3135796c8dcSSimon Schubert
3145796c8dcSSimon Schubert %token <comp> NAME
3155796c8dcSSimon Schubert %type <comp> name
3165796c8dcSSimon Schubert
3175796c8dcSSimon Schubert %token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON
3185796c8dcSSimon Schubert %token TEMPLATE
3195796c8dcSSimon Schubert %token ERROR
3205796c8dcSSimon Schubert %token NEW DELETE OPERATOR
3215796c8dcSSimon Schubert %token STATIC_CAST REINTERPRET_CAST DYNAMIC_CAST
3225796c8dcSSimon Schubert
3235796c8dcSSimon Schubert /* Special type cases, put in to allow the parser to distinguish different
3245796c8dcSSimon Schubert legal basetypes. */
3255796c8dcSSimon Schubert %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD BOOL
3265796c8dcSSimon Schubert %token ELLIPSIS RESTRICT VOID FLOAT_KEYWORD CHAR WCHAR_T
3275796c8dcSSimon Schubert
3285796c8dcSSimon Schubert %token <opname> ASSIGN_MODIFY
3295796c8dcSSimon Schubert
3305796c8dcSSimon Schubert /* C++ */
3315796c8dcSSimon Schubert %token TRUEKEYWORD
3325796c8dcSSimon Schubert %token FALSEKEYWORD
3335796c8dcSSimon Schubert
3345796c8dcSSimon Schubert /* Non-C++ things we get from the demangler. */
3355796c8dcSSimon Schubert %token <lval> DEMANGLER_SPECIAL
3365796c8dcSSimon Schubert %token CONSTRUCTION_VTABLE CONSTRUCTION_IN
3375796c8dcSSimon Schubert
3385796c8dcSSimon Schubert /* Precedence declarations. */
3395796c8dcSSimon Schubert
3405796c8dcSSimon Schubert /* Give NAME lower precedence than COLONCOLON, so that nested_name will
3415796c8dcSSimon Schubert associate greedily. */
3425796c8dcSSimon Schubert %nonassoc NAME
3435796c8dcSSimon Schubert
3445796c8dcSSimon Schubert /* Give NEW and DELETE lower precedence than ']', because we can not
3455796c8dcSSimon Schubert have an array of type operator new. This causes NEW '[' to be
3465796c8dcSSimon Schubert parsed as operator new[]. */
3475796c8dcSSimon Schubert %nonassoc NEW DELETE
3485796c8dcSSimon Schubert
3495796c8dcSSimon Schubert /* Give VOID higher precedence than NAME. Then we can use %prec NAME
3505796c8dcSSimon Schubert to prefer (VOID) to (function_args). */
3515796c8dcSSimon Schubert %nonassoc VOID
3525796c8dcSSimon Schubert
3535796c8dcSSimon Schubert /* Give VOID lower precedence than ')' for similar reasons. */
3545796c8dcSSimon Schubert %nonassoc ')'
3555796c8dcSSimon Schubert
3565796c8dcSSimon Schubert %left ','
3575796c8dcSSimon Schubert %right '=' ASSIGN_MODIFY
3585796c8dcSSimon Schubert %right '?'
3595796c8dcSSimon Schubert %left OROR
3605796c8dcSSimon Schubert %left ANDAND
3615796c8dcSSimon Schubert %left '|'
3625796c8dcSSimon Schubert %left '^'
3635796c8dcSSimon Schubert %left '&'
3645796c8dcSSimon Schubert %left EQUAL NOTEQUAL
3655796c8dcSSimon Schubert %left '<' '>' LEQ GEQ
3665796c8dcSSimon Schubert %left LSH RSH
3675796c8dcSSimon Schubert %left '@'
3685796c8dcSSimon Schubert %left '+' '-'
3695796c8dcSSimon Schubert %left '*' '/' '%'
3705796c8dcSSimon Schubert %right UNARY INCREMENT DECREMENT
3715796c8dcSSimon Schubert
3725796c8dcSSimon Schubert /* We don't need a precedence for '(' in this reduced grammar, and it
3735796c8dcSSimon Schubert can mask some unpleasant bugs, so disable it for now. */
3745796c8dcSSimon Schubert
3755796c8dcSSimon Schubert %right ARROW '.' '[' /* '(' */
3765796c8dcSSimon Schubert %left COLONCOLON
3775796c8dcSSimon Schubert
3785796c8dcSSimon Schubert
3795796c8dcSSimon Schubert %%
3805796c8dcSSimon Schubert
3815796c8dcSSimon Schubert result : start
3825796c8dcSSimon Schubert { global_result = $1; }
3835796c8dcSSimon Schubert ;
3845796c8dcSSimon Schubert
3855796c8dcSSimon Schubert start : type
3865796c8dcSSimon Schubert
3875796c8dcSSimon Schubert | demangler_special
3885796c8dcSSimon Schubert
3895796c8dcSSimon Schubert | function
3905796c8dcSSimon Schubert
3915796c8dcSSimon Schubert ;
3925796c8dcSSimon Schubert
3935796c8dcSSimon Schubert start_opt : /* */
3945796c8dcSSimon Schubert { $$ = NULL; }
3955796c8dcSSimon Schubert | COLONCOLON start
3965796c8dcSSimon Schubert { $$ = $2; }
3975796c8dcSSimon Schubert ;
3985796c8dcSSimon Schubert
3995796c8dcSSimon Schubert function
4005796c8dcSSimon Schubert /* Function with a return type. declarator_1 is used to prevent
4015796c8dcSSimon Schubert ambiguity with the next rule. */
4025796c8dcSSimon Schubert : typespec_2 declarator_1
4035796c8dcSSimon Schubert { $$ = $2.comp;
4045796c8dcSSimon Schubert *$2.last = $1;
4055796c8dcSSimon Schubert }
4065796c8dcSSimon Schubert
4075796c8dcSSimon Schubert /* Function without a return type. We need to use typespec_2
4085796c8dcSSimon Schubert to prevent conflicts from qualifiers_opt - harmless. The
4095796c8dcSSimon Schubert start_opt is used to handle "function-local" variables and
4105796c8dcSSimon Schubert types. */
4115796c8dcSSimon Schubert | typespec_2 function_arglist start_opt
4125796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
4135796c8dcSSimon Schubert if ($3) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
4145796c8dcSSimon Schubert | colon_ext_only function_arglist start_opt
4155796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
4165796c8dcSSimon Schubert if ($3) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
4175796c8dcSSimon Schubert
4185796c8dcSSimon Schubert | conversion_op_name start_opt
4195796c8dcSSimon Schubert { $$ = $1.comp;
4205796c8dcSSimon Schubert if ($2) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2); }
4215796c8dcSSimon Schubert | conversion_op_name abstract_declarator_fn
4225796c8dcSSimon Schubert { if ($2.last)
4235796c8dcSSimon Schubert {
4245796c8dcSSimon Schubert /* First complete the abstract_declarator's type using
4255796c8dcSSimon Schubert the typespec from the conversion_op_name. */
4265796c8dcSSimon Schubert *$2.last = *$1.last;
4275796c8dcSSimon Schubert /* Then complete the conversion_op_name with the type. */
4285796c8dcSSimon Schubert *$1.last = $2.comp;
4295796c8dcSSimon Schubert }
4305796c8dcSSimon Schubert /* If we have an arglist, build a function type. */
4315796c8dcSSimon Schubert if ($2.fn.comp)
4325796c8dcSSimon Schubert $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1.comp, $2.fn.comp);
4335796c8dcSSimon Schubert else
4345796c8dcSSimon Schubert $$ = $1.comp;
4355796c8dcSSimon Schubert if ($2.start) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2.start);
4365796c8dcSSimon Schubert }
4375796c8dcSSimon Schubert ;
4385796c8dcSSimon Schubert
4395796c8dcSSimon Schubert demangler_special
4405796c8dcSSimon Schubert : DEMANGLER_SPECIAL start
4415796c8dcSSimon Schubert { $$ = make_empty ($1);
4425796c8dcSSimon Schubert d_left ($$) = $2;
4435796c8dcSSimon Schubert d_right ($$) = NULL; }
4445796c8dcSSimon Schubert | CONSTRUCTION_VTABLE start CONSTRUCTION_IN start
4455796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, $2, $4); }
4465796c8dcSSimon Schubert ;
4475796c8dcSSimon Schubert
4485796c8dcSSimon Schubert operator : OPERATOR NEW
449*ef5ccd6cSJohn Marino {
450*ef5ccd6cSJohn Marino /* Match the whitespacing of cplus_demangle_operators.
451*ef5ccd6cSJohn Marino It would abort on unrecognized string otherwise. */
452*ef5ccd6cSJohn Marino $$ = make_operator ("new", 3);
453*ef5ccd6cSJohn Marino }
4545796c8dcSSimon Schubert | OPERATOR DELETE
455*ef5ccd6cSJohn Marino {
456*ef5ccd6cSJohn Marino /* Match the whitespacing of cplus_demangle_operators.
457*ef5ccd6cSJohn Marino It would abort on unrecognized string otherwise. */
458*ef5ccd6cSJohn Marino $$ = make_operator ("delete ", 1);
459*ef5ccd6cSJohn Marino }
4605796c8dcSSimon Schubert | OPERATOR NEW '[' ']'
461*ef5ccd6cSJohn Marino {
462*ef5ccd6cSJohn Marino /* Match the whitespacing of cplus_demangle_operators.
463*ef5ccd6cSJohn Marino It would abort on unrecognized string otherwise. */
464*ef5ccd6cSJohn Marino $$ = make_operator ("new[]", 3);
465*ef5ccd6cSJohn Marino }
4665796c8dcSSimon Schubert | OPERATOR DELETE '[' ']'
467*ef5ccd6cSJohn Marino {
468*ef5ccd6cSJohn Marino /* Match the whitespacing of cplus_demangle_operators.
469*ef5ccd6cSJohn Marino It would abort on unrecognized string otherwise. */
470*ef5ccd6cSJohn Marino $$ = make_operator ("delete[] ", 1);
471*ef5ccd6cSJohn Marino }
4725796c8dcSSimon Schubert | OPERATOR '+'
4735796c8dcSSimon Schubert { $$ = make_operator ("+", 2); }
4745796c8dcSSimon Schubert | OPERATOR '-'
4755796c8dcSSimon Schubert { $$ = make_operator ("-", 2); }
4765796c8dcSSimon Schubert | OPERATOR '*'
4775796c8dcSSimon Schubert { $$ = make_operator ("*", 2); }
4785796c8dcSSimon Schubert | OPERATOR '/'
4795796c8dcSSimon Schubert { $$ = make_operator ("/", 2); }
4805796c8dcSSimon Schubert | OPERATOR '%'
4815796c8dcSSimon Schubert { $$ = make_operator ("%", 2); }
4825796c8dcSSimon Schubert | OPERATOR '^'
4835796c8dcSSimon Schubert { $$ = make_operator ("^", 2); }
4845796c8dcSSimon Schubert | OPERATOR '&'
4855796c8dcSSimon Schubert { $$ = make_operator ("&", 2); }
4865796c8dcSSimon Schubert | OPERATOR '|'
4875796c8dcSSimon Schubert { $$ = make_operator ("|", 2); }
4885796c8dcSSimon Schubert | OPERATOR '~'
4895796c8dcSSimon Schubert { $$ = make_operator ("~", 1); }
4905796c8dcSSimon Schubert | OPERATOR '!'
4915796c8dcSSimon Schubert { $$ = make_operator ("!", 1); }
4925796c8dcSSimon Schubert | OPERATOR '='
4935796c8dcSSimon Schubert { $$ = make_operator ("=", 2); }
4945796c8dcSSimon Schubert | OPERATOR '<'
4955796c8dcSSimon Schubert { $$ = make_operator ("<", 2); }
4965796c8dcSSimon Schubert | OPERATOR '>'
4975796c8dcSSimon Schubert { $$ = make_operator (">", 2); }
4985796c8dcSSimon Schubert | OPERATOR ASSIGN_MODIFY
4995796c8dcSSimon Schubert { $$ = make_operator ($2, 2); }
5005796c8dcSSimon Schubert | OPERATOR LSH
5015796c8dcSSimon Schubert { $$ = make_operator ("<<", 2); }
5025796c8dcSSimon Schubert | OPERATOR RSH
5035796c8dcSSimon Schubert { $$ = make_operator (">>", 2); }
5045796c8dcSSimon Schubert | OPERATOR EQUAL
5055796c8dcSSimon Schubert { $$ = make_operator ("==", 2); }
5065796c8dcSSimon Schubert | OPERATOR NOTEQUAL
5075796c8dcSSimon Schubert { $$ = make_operator ("!=", 2); }
5085796c8dcSSimon Schubert | OPERATOR LEQ
5095796c8dcSSimon Schubert { $$ = make_operator ("<=", 2); }
5105796c8dcSSimon Schubert | OPERATOR GEQ
5115796c8dcSSimon Schubert { $$ = make_operator (">=", 2); }
5125796c8dcSSimon Schubert | OPERATOR ANDAND
5135796c8dcSSimon Schubert { $$ = make_operator ("&&", 2); }
5145796c8dcSSimon Schubert | OPERATOR OROR
5155796c8dcSSimon Schubert { $$ = make_operator ("||", 2); }
5165796c8dcSSimon Schubert | OPERATOR INCREMENT
5175796c8dcSSimon Schubert { $$ = make_operator ("++", 1); }
5185796c8dcSSimon Schubert | OPERATOR DECREMENT
5195796c8dcSSimon Schubert { $$ = make_operator ("--", 1); }
5205796c8dcSSimon Schubert | OPERATOR ','
5215796c8dcSSimon Schubert { $$ = make_operator (",", 2); }
5225796c8dcSSimon Schubert | OPERATOR ARROW '*'
5235796c8dcSSimon Schubert { $$ = make_operator ("->*", 2); }
5245796c8dcSSimon Schubert | OPERATOR ARROW
5255796c8dcSSimon Schubert { $$ = make_operator ("->", 2); }
5265796c8dcSSimon Schubert | OPERATOR '(' ')'
5275796c8dcSSimon Schubert { $$ = make_operator ("()", 2); }
5285796c8dcSSimon Schubert | OPERATOR '[' ']'
5295796c8dcSSimon Schubert { $$ = make_operator ("[]", 2); }
5305796c8dcSSimon Schubert ;
5315796c8dcSSimon Schubert
5325796c8dcSSimon Schubert /* Conversion operators. We don't try to handle some of
5335796c8dcSSimon Schubert the wackier demangler output for function pointers,
5345796c8dcSSimon Schubert since it's not clear that it's parseable. */
5355796c8dcSSimon Schubert conversion_op
5365796c8dcSSimon Schubert : OPERATOR typespec_2
5375796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_CAST, $2, NULL); }
5385796c8dcSSimon Schubert ;
5395796c8dcSSimon Schubert
5405796c8dcSSimon Schubert conversion_op_name
5415796c8dcSSimon Schubert : nested_name conversion_op
5425796c8dcSSimon Schubert { $$.comp = $1.comp;
5435796c8dcSSimon Schubert d_right ($1.last) = $2;
5445796c8dcSSimon Schubert $$.last = &d_left ($2);
5455796c8dcSSimon Schubert }
5465796c8dcSSimon Schubert | conversion_op
5475796c8dcSSimon Schubert { $$.comp = $1;
5485796c8dcSSimon Schubert $$.last = &d_left ($1);
5495796c8dcSSimon Schubert }
5505796c8dcSSimon Schubert | COLONCOLON nested_name conversion_op
5515796c8dcSSimon Schubert { $$.comp = $2.comp;
5525796c8dcSSimon Schubert d_right ($2.last) = $3;
5535796c8dcSSimon Schubert $$.last = &d_left ($3);
5545796c8dcSSimon Schubert }
5555796c8dcSSimon Schubert | COLONCOLON conversion_op
5565796c8dcSSimon Schubert { $$.comp = $2;
5575796c8dcSSimon Schubert $$.last = &d_left ($2);
5585796c8dcSSimon Schubert }
5595796c8dcSSimon Schubert ;
5605796c8dcSSimon Schubert
5615796c8dcSSimon Schubert /* DEMANGLE_COMPONENT_NAME */
5625796c8dcSSimon Schubert /* This accepts certain invalid placements of '~'. */
5635796c8dcSSimon Schubert unqualified_name: operator
5645796c8dcSSimon Schubert | operator '<' template_params '>'
5655796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
5665796c8dcSSimon Schubert | '~' NAME
5675796c8dcSSimon Schubert { $$ = make_dtor (gnu_v3_complete_object_dtor, $2); }
5685796c8dcSSimon Schubert ;
5695796c8dcSSimon Schubert
5705796c8dcSSimon Schubert /* This rule is used in name and nested_name, and expanded inline there
5715796c8dcSSimon Schubert for efficiency. */
5725796c8dcSSimon Schubert /*
5735796c8dcSSimon Schubert scope_id : NAME
5745796c8dcSSimon Schubert | template
5755796c8dcSSimon Schubert ;
5765796c8dcSSimon Schubert */
5775796c8dcSSimon Schubert
5785796c8dcSSimon Schubert colon_name : name
5795796c8dcSSimon Schubert | COLONCOLON name
5805796c8dcSSimon Schubert { $$ = $2; }
5815796c8dcSSimon Schubert ;
5825796c8dcSSimon Schubert
5835796c8dcSSimon Schubert /* DEMANGLE_COMPONENT_QUAL_NAME */
5845796c8dcSSimon Schubert /* DEMANGLE_COMPONENT_CTOR / DEMANGLE_COMPONENT_DTOR ? */
5855796c8dcSSimon Schubert name : nested_name NAME %prec NAME
5865796c8dcSSimon Schubert { $$ = $1.comp; d_right ($1.last) = $2; }
5875796c8dcSSimon Schubert | NAME %prec NAME
5885796c8dcSSimon Schubert | nested_name template %prec NAME
5895796c8dcSSimon Schubert { $$ = $1.comp; d_right ($1.last) = $2; }
5905796c8dcSSimon Schubert | template %prec NAME
5915796c8dcSSimon Schubert ;
5925796c8dcSSimon Schubert
5935796c8dcSSimon Schubert colon_ext_name : colon_name
5945796c8dcSSimon Schubert | colon_ext_only
5955796c8dcSSimon Schubert ;
5965796c8dcSSimon Schubert
5975796c8dcSSimon Schubert colon_ext_only : ext_only_name
5985796c8dcSSimon Schubert | COLONCOLON ext_only_name
5995796c8dcSSimon Schubert { $$ = $2; }
6005796c8dcSSimon Schubert ;
6015796c8dcSSimon Schubert
6025796c8dcSSimon Schubert ext_only_name : nested_name unqualified_name
6035796c8dcSSimon Schubert { $$ = $1.comp; d_right ($1.last) = $2; }
6045796c8dcSSimon Schubert | unqualified_name
6055796c8dcSSimon Schubert ;
6065796c8dcSSimon Schubert
6075796c8dcSSimon Schubert nested_name : NAME COLONCOLON
6085796c8dcSSimon Schubert { $$.comp = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
6095796c8dcSSimon Schubert d_left ($$.comp) = $1;
6105796c8dcSSimon Schubert d_right ($$.comp) = NULL;
6115796c8dcSSimon Schubert $$.last = $$.comp;
6125796c8dcSSimon Schubert }
6135796c8dcSSimon Schubert | nested_name NAME COLONCOLON
6145796c8dcSSimon Schubert { $$.comp = $1.comp;
6155796c8dcSSimon Schubert d_right ($1.last) = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
6165796c8dcSSimon Schubert $$.last = d_right ($1.last);
6175796c8dcSSimon Schubert d_left ($$.last) = $2;
6185796c8dcSSimon Schubert d_right ($$.last) = NULL;
6195796c8dcSSimon Schubert }
6205796c8dcSSimon Schubert | template COLONCOLON
6215796c8dcSSimon Schubert { $$.comp = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
6225796c8dcSSimon Schubert d_left ($$.comp) = $1;
6235796c8dcSSimon Schubert d_right ($$.comp) = NULL;
6245796c8dcSSimon Schubert $$.last = $$.comp;
6255796c8dcSSimon Schubert }
6265796c8dcSSimon Schubert | nested_name template COLONCOLON
6275796c8dcSSimon Schubert { $$.comp = $1.comp;
6285796c8dcSSimon Schubert d_right ($1.last) = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
6295796c8dcSSimon Schubert $$.last = d_right ($1.last);
6305796c8dcSSimon Schubert d_left ($$.last) = $2;
6315796c8dcSSimon Schubert d_right ($$.last) = NULL;
6325796c8dcSSimon Schubert }
6335796c8dcSSimon Schubert ;
6345796c8dcSSimon Schubert
6355796c8dcSSimon Schubert /* DEMANGLE_COMPONENT_TEMPLATE */
6365796c8dcSSimon Schubert /* DEMANGLE_COMPONENT_TEMPLATE_ARGLIST */
6375796c8dcSSimon Schubert template : NAME '<' template_params '>'
6385796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
6395796c8dcSSimon Schubert ;
6405796c8dcSSimon Schubert
6415796c8dcSSimon Schubert template_params : template_arg
6425796c8dcSSimon Schubert { $$.comp = fill_comp (DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, $1, NULL);
6435796c8dcSSimon Schubert $$.last = &d_right ($$.comp); }
6445796c8dcSSimon Schubert | template_params ',' template_arg
6455796c8dcSSimon Schubert { $$.comp = $1.comp;
6465796c8dcSSimon Schubert *$1.last = fill_comp (DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, $3, NULL);
6475796c8dcSSimon Schubert $$.last = &d_right (*$1.last);
6485796c8dcSSimon Schubert }
6495796c8dcSSimon Schubert ;
6505796c8dcSSimon Schubert
6515796c8dcSSimon Schubert /* "type" is inlined into template_arg and function_args. */
6525796c8dcSSimon Schubert
6535796c8dcSSimon Schubert /* Also an integral constant-expression of integral type, and a
6545796c8dcSSimon Schubert pointer to member (?) */
6555796c8dcSSimon Schubert template_arg : typespec_2
6565796c8dcSSimon Schubert | typespec_2 abstract_declarator
6575796c8dcSSimon Schubert { $$ = $2.comp;
6585796c8dcSSimon Schubert *$2.last = $1;
6595796c8dcSSimon Schubert }
6605796c8dcSSimon Schubert | '&' start
6615796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $2); }
6625796c8dcSSimon Schubert | '&' '(' start ')'
6635796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $3); }
6645796c8dcSSimon Schubert | exp
6655796c8dcSSimon Schubert ;
6665796c8dcSSimon Schubert
6675796c8dcSSimon Schubert function_args : typespec_2
6685796c8dcSSimon Schubert { $$.comp = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $1, NULL);
6695796c8dcSSimon Schubert $$.last = &d_right ($$.comp);
6705796c8dcSSimon Schubert }
6715796c8dcSSimon Schubert | typespec_2 abstract_declarator
6725796c8dcSSimon Schubert { *$2.last = $1;
6735796c8dcSSimon Schubert $$.comp = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $2.comp, NULL);
6745796c8dcSSimon Schubert $$.last = &d_right ($$.comp);
6755796c8dcSSimon Schubert }
6765796c8dcSSimon Schubert | function_args ',' typespec_2
6775796c8dcSSimon Schubert { *$1.last = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $3, NULL);
6785796c8dcSSimon Schubert $$.comp = $1.comp;
6795796c8dcSSimon Schubert $$.last = &d_right (*$1.last);
6805796c8dcSSimon Schubert }
6815796c8dcSSimon Schubert | function_args ',' typespec_2 abstract_declarator
6825796c8dcSSimon Schubert { *$4.last = $3;
6835796c8dcSSimon Schubert *$1.last = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $4.comp, NULL);
6845796c8dcSSimon Schubert $$.comp = $1.comp;
6855796c8dcSSimon Schubert $$.last = &d_right (*$1.last);
6865796c8dcSSimon Schubert }
6875796c8dcSSimon Schubert | function_args ',' ELLIPSIS
6885796c8dcSSimon Schubert { *$1.last
6895796c8dcSSimon Schubert = fill_comp (DEMANGLE_COMPONENT_ARGLIST,
6905796c8dcSSimon Schubert make_builtin_type ("..."),
6915796c8dcSSimon Schubert NULL);
6925796c8dcSSimon Schubert $$.comp = $1.comp;
6935796c8dcSSimon Schubert $$.last = &d_right (*$1.last);
6945796c8dcSSimon Schubert }
6955796c8dcSSimon Schubert ;
6965796c8dcSSimon Schubert
6975796c8dcSSimon Schubert function_arglist: '(' function_args ')' qualifiers_opt %prec NAME
6985796c8dcSSimon Schubert { $$.comp = fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, $2.comp);
6995796c8dcSSimon Schubert $$.last = &d_left ($$.comp);
7005796c8dcSSimon Schubert $$.comp = d_qualify ($$.comp, $4, 1); }
7015796c8dcSSimon Schubert | '(' VOID ')' qualifiers_opt
7025796c8dcSSimon Schubert { $$.comp = fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, NULL);
7035796c8dcSSimon Schubert $$.last = &d_left ($$.comp);
7045796c8dcSSimon Schubert $$.comp = d_qualify ($$.comp, $4, 1); }
7055796c8dcSSimon Schubert | '(' ')' qualifiers_opt
7065796c8dcSSimon Schubert { $$.comp = fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, NULL);
7075796c8dcSSimon Schubert $$.last = &d_left ($$.comp);
7085796c8dcSSimon Schubert $$.comp = d_qualify ($$.comp, $3, 1); }
7095796c8dcSSimon Schubert ;
7105796c8dcSSimon Schubert
7115796c8dcSSimon Schubert /* Should do something about DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL */
7125796c8dcSSimon Schubert qualifiers_opt : /* epsilon */
7135796c8dcSSimon Schubert { $$ = 0; }
7145796c8dcSSimon Schubert | qualifiers
7155796c8dcSSimon Schubert ;
7165796c8dcSSimon Schubert
7175796c8dcSSimon Schubert qualifier : RESTRICT
7185796c8dcSSimon Schubert { $$ = QUAL_RESTRICT; }
7195796c8dcSSimon Schubert | VOLATILE_KEYWORD
7205796c8dcSSimon Schubert { $$ = QUAL_VOLATILE; }
7215796c8dcSSimon Schubert | CONST_KEYWORD
7225796c8dcSSimon Schubert { $$ = QUAL_CONST; }
7235796c8dcSSimon Schubert ;
7245796c8dcSSimon Schubert
7255796c8dcSSimon Schubert qualifiers : qualifier
7265796c8dcSSimon Schubert | qualifier qualifiers
7275796c8dcSSimon Schubert { $$ = $1 | $2; }
7285796c8dcSSimon Schubert ;
7295796c8dcSSimon Schubert
7305796c8dcSSimon Schubert /* This accepts all sorts of invalid constructions and produces
7315796c8dcSSimon Schubert invalid output for them - an error would be better. */
7325796c8dcSSimon Schubert
7335796c8dcSSimon Schubert int_part : INT_KEYWORD
7345796c8dcSSimon Schubert { $$ = 0; }
7355796c8dcSSimon Schubert | SIGNED_KEYWORD
7365796c8dcSSimon Schubert { $$ = INT_SIGNED; }
7375796c8dcSSimon Schubert | UNSIGNED
7385796c8dcSSimon Schubert { $$ = INT_UNSIGNED; }
7395796c8dcSSimon Schubert | CHAR
7405796c8dcSSimon Schubert { $$ = INT_CHAR; }
7415796c8dcSSimon Schubert | LONG
7425796c8dcSSimon Schubert { $$ = INT_LONG; }
7435796c8dcSSimon Schubert | SHORT
7445796c8dcSSimon Schubert { $$ = INT_SHORT; }
7455796c8dcSSimon Schubert ;
7465796c8dcSSimon Schubert
7475796c8dcSSimon Schubert int_seq : int_part
7485796c8dcSSimon Schubert | int_seq int_part
7495796c8dcSSimon Schubert { $$ = $1 | $2; if ($1 & $2 & INT_LONG) $$ = $1 | INT_LLONG; }
7505796c8dcSSimon Schubert ;
7515796c8dcSSimon Schubert
7525796c8dcSSimon Schubert builtin_type : int_seq
7535796c8dcSSimon Schubert { $$ = d_int_type ($1); }
7545796c8dcSSimon Schubert | FLOAT_KEYWORD
7555796c8dcSSimon Schubert { $$ = make_builtin_type ("float"); }
7565796c8dcSSimon Schubert | DOUBLE_KEYWORD
7575796c8dcSSimon Schubert { $$ = make_builtin_type ("double"); }
7585796c8dcSSimon Schubert | LONG DOUBLE_KEYWORD
7595796c8dcSSimon Schubert { $$ = make_builtin_type ("long double"); }
7605796c8dcSSimon Schubert | BOOL
7615796c8dcSSimon Schubert { $$ = make_builtin_type ("bool"); }
7625796c8dcSSimon Schubert | WCHAR_T
7635796c8dcSSimon Schubert { $$ = make_builtin_type ("wchar_t"); }
7645796c8dcSSimon Schubert | VOID
7655796c8dcSSimon Schubert { $$ = make_builtin_type ("void"); }
7665796c8dcSSimon Schubert ;
7675796c8dcSSimon Schubert
7685796c8dcSSimon Schubert ptr_operator : '*' qualifiers_opt
7695796c8dcSSimon Schubert { $$.comp = make_empty (DEMANGLE_COMPONENT_POINTER);
7705796c8dcSSimon Schubert $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
7715796c8dcSSimon Schubert $$.last = &d_left ($$.comp);
7725796c8dcSSimon Schubert $$.comp = d_qualify ($$.comp, $2, 0); }
7735796c8dcSSimon Schubert /* g++ seems to allow qualifiers after the reference? */
7745796c8dcSSimon Schubert | '&'
7755796c8dcSSimon Schubert { $$.comp = make_empty (DEMANGLE_COMPONENT_REFERENCE);
7765796c8dcSSimon Schubert $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
7775796c8dcSSimon Schubert $$.last = &d_left ($$.comp); }
7785796c8dcSSimon Schubert | nested_name '*' qualifiers_opt
7795796c8dcSSimon Schubert { $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
7805796c8dcSSimon Schubert $$.comp->u.s_binary.left = $1.comp;
7815796c8dcSSimon Schubert /* Convert the innermost DEMANGLE_COMPONENT_QUAL_NAME to a DEMANGLE_COMPONENT_NAME. */
7825796c8dcSSimon Schubert *$1.last = *d_left ($1.last);
7835796c8dcSSimon Schubert $$.comp->u.s_binary.right = NULL;
7845796c8dcSSimon Schubert $$.last = &d_right ($$.comp);
7855796c8dcSSimon Schubert $$.comp = d_qualify ($$.comp, $3, 0); }
7865796c8dcSSimon Schubert | COLONCOLON nested_name '*' qualifiers_opt
7875796c8dcSSimon Schubert { $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
7885796c8dcSSimon Schubert $$.comp->u.s_binary.left = $2.comp;
7895796c8dcSSimon Schubert /* Convert the innermost DEMANGLE_COMPONENT_QUAL_NAME to a DEMANGLE_COMPONENT_NAME. */
7905796c8dcSSimon Schubert *$2.last = *d_left ($2.last);
7915796c8dcSSimon Schubert $$.comp->u.s_binary.right = NULL;
7925796c8dcSSimon Schubert $$.last = &d_right ($$.comp);
7935796c8dcSSimon Schubert $$.comp = d_qualify ($$.comp, $4, 0); }
7945796c8dcSSimon Schubert ;
7955796c8dcSSimon Schubert
7965796c8dcSSimon Schubert array_indicator : '[' ']'
7975796c8dcSSimon Schubert { $$ = make_empty (DEMANGLE_COMPONENT_ARRAY_TYPE);
7985796c8dcSSimon Schubert d_left ($$) = NULL;
7995796c8dcSSimon Schubert }
8005796c8dcSSimon Schubert | '[' INT ']'
8015796c8dcSSimon Schubert { $$ = make_empty (DEMANGLE_COMPONENT_ARRAY_TYPE);
8025796c8dcSSimon Schubert d_left ($$) = $2;
8035796c8dcSSimon Schubert }
8045796c8dcSSimon Schubert ;
8055796c8dcSSimon Schubert
8065796c8dcSSimon Schubert /* Details of this approach inspired by the G++ < 3.4 parser. */
8075796c8dcSSimon Schubert
8085796c8dcSSimon Schubert /* This rule is only used in typespec_2, and expanded inline there for
8095796c8dcSSimon Schubert efficiency. */
8105796c8dcSSimon Schubert /*
8115796c8dcSSimon Schubert typespec : builtin_type
8125796c8dcSSimon Schubert | colon_name
8135796c8dcSSimon Schubert ;
8145796c8dcSSimon Schubert */
8155796c8dcSSimon Schubert
8165796c8dcSSimon Schubert typespec_2 : builtin_type qualifiers
8175796c8dcSSimon Schubert { $$ = d_qualify ($1, $2, 0); }
8185796c8dcSSimon Schubert | builtin_type
8195796c8dcSSimon Schubert | qualifiers builtin_type qualifiers
8205796c8dcSSimon Schubert { $$ = d_qualify ($2, $1 | $3, 0); }
8215796c8dcSSimon Schubert | qualifiers builtin_type
8225796c8dcSSimon Schubert { $$ = d_qualify ($2, $1, 0); }
8235796c8dcSSimon Schubert
8245796c8dcSSimon Schubert | name qualifiers
8255796c8dcSSimon Schubert { $$ = d_qualify ($1, $2, 0); }
8265796c8dcSSimon Schubert | name
8275796c8dcSSimon Schubert | qualifiers name qualifiers
8285796c8dcSSimon Schubert { $$ = d_qualify ($2, $1 | $3, 0); }
8295796c8dcSSimon Schubert | qualifiers name
8305796c8dcSSimon Schubert { $$ = d_qualify ($2, $1, 0); }
8315796c8dcSSimon Schubert
8325796c8dcSSimon Schubert | COLONCOLON name qualifiers
8335796c8dcSSimon Schubert { $$ = d_qualify ($2, $3, 0); }
8345796c8dcSSimon Schubert | COLONCOLON name
8355796c8dcSSimon Schubert { $$ = $2; }
8365796c8dcSSimon Schubert | qualifiers COLONCOLON name qualifiers
8375796c8dcSSimon Schubert { $$ = d_qualify ($3, $1 | $4, 0); }
8385796c8dcSSimon Schubert | qualifiers COLONCOLON name
8395796c8dcSSimon Schubert { $$ = d_qualify ($3, $1, 0); }
8405796c8dcSSimon Schubert ;
8415796c8dcSSimon Schubert
8425796c8dcSSimon Schubert abstract_declarator
8435796c8dcSSimon Schubert : ptr_operator
8445796c8dcSSimon Schubert { $$.comp = $1.comp; $$.last = $1.last;
8455796c8dcSSimon Schubert $$.fn.comp = NULL; $$.fn.last = NULL; }
8465796c8dcSSimon Schubert | ptr_operator abstract_declarator
8475796c8dcSSimon Schubert { $$ = $2; $$.fn.comp = NULL; $$.fn.last = NULL;
8485796c8dcSSimon Schubert if ($2.fn.comp) { $$.last = $2.fn.last; *$2.last = $2.fn.comp; }
8495796c8dcSSimon Schubert *$$.last = $1.comp;
8505796c8dcSSimon Schubert $$.last = $1.last; }
8515796c8dcSSimon Schubert | direct_abstract_declarator
8525796c8dcSSimon Schubert { $$.fn.comp = NULL; $$.fn.last = NULL;
8535796c8dcSSimon Schubert if ($1.fn.comp) { $$.last = $1.fn.last; *$1.last = $1.fn.comp; }
8545796c8dcSSimon Schubert }
8555796c8dcSSimon Schubert ;
8565796c8dcSSimon Schubert
8575796c8dcSSimon Schubert direct_abstract_declarator
8585796c8dcSSimon Schubert : '(' abstract_declarator ')'
8595796c8dcSSimon Schubert { $$ = $2; $$.fn.comp = NULL; $$.fn.last = NULL; $$.fold_flag = 1;
8605796c8dcSSimon Schubert if ($2.fn.comp) { $$.last = $2.fn.last; *$2.last = $2.fn.comp; }
8615796c8dcSSimon Schubert }
8625796c8dcSSimon Schubert | direct_abstract_declarator function_arglist
8635796c8dcSSimon Schubert { $$.fold_flag = 0;
8645796c8dcSSimon Schubert if ($1.fn.comp) { $$.last = $1.fn.last; *$1.last = $1.fn.comp; }
8655796c8dcSSimon Schubert if ($1.fold_flag)
8665796c8dcSSimon Schubert {
8675796c8dcSSimon Schubert *$$.last = $2.comp;
8685796c8dcSSimon Schubert $$.last = $2.last;
8695796c8dcSSimon Schubert }
8705796c8dcSSimon Schubert else
8715796c8dcSSimon Schubert $$.fn = $2;
8725796c8dcSSimon Schubert }
8735796c8dcSSimon Schubert | direct_abstract_declarator array_indicator
8745796c8dcSSimon Schubert { $$.fn.comp = NULL; $$.fn.last = NULL; $$.fold_flag = 0;
8755796c8dcSSimon Schubert if ($1.fn.comp) { $$.last = $1.fn.last; *$1.last = $1.fn.comp; }
8765796c8dcSSimon Schubert *$1.last = $2;
8775796c8dcSSimon Schubert $$.last = &d_right ($2);
8785796c8dcSSimon Schubert }
8795796c8dcSSimon Schubert | array_indicator
8805796c8dcSSimon Schubert { $$.fn.comp = NULL; $$.fn.last = NULL; $$.fold_flag = 0;
8815796c8dcSSimon Schubert $$.comp = $1;
8825796c8dcSSimon Schubert $$.last = &d_right ($1);
8835796c8dcSSimon Schubert }
8845796c8dcSSimon Schubert /* G++ has the following except for () and (type). Then
8855796c8dcSSimon Schubert (type) is handled in regcast_or_absdcl and () is handled
8865796c8dcSSimon Schubert in fcast_or_absdcl.
8875796c8dcSSimon Schubert
8885796c8dcSSimon Schubert However, this is only useful for function types, and
8895796c8dcSSimon Schubert generates reduce/reduce conflicts with direct_declarator.
8905796c8dcSSimon Schubert We're interested in pointer-to-function types, and in
8915796c8dcSSimon Schubert functions, but not in function types - so leave this
8925796c8dcSSimon Schubert out. */
8935796c8dcSSimon Schubert /* | function_arglist */
8945796c8dcSSimon Schubert ;
8955796c8dcSSimon Schubert
8965796c8dcSSimon Schubert abstract_declarator_fn
8975796c8dcSSimon Schubert : ptr_operator
8985796c8dcSSimon Schubert { $$.comp = $1.comp; $$.last = $1.last;
8995796c8dcSSimon Schubert $$.fn.comp = NULL; $$.fn.last = NULL; $$.start = NULL; }
9005796c8dcSSimon Schubert | ptr_operator abstract_declarator_fn
9015796c8dcSSimon Schubert { $$ = $2;
9025796c8dcSSimon Schubert if ($2.last)
9035796c8dcSSimon Schubert *$$.last = $1.comp;
9045796c8dcSSimon Schubert else
9055796c8dcSSimon Schubert $$.comp = $1.comp;
9065796c8dcSSimon Schubert $$.last = $1.last;
9075796c8dcSSimon Schubert }
9085796c8dcSSimon Schubert | direct_abstract_declarator
9095796c8dcSSimon Schubert { $$.comp = $1.comp; $$.last = $1.last; $$.fn = $1.fn; $$.start = NULL; }
9105796c8dcSSimon Schubert | direct_abstract_declarator function_arglist COLONCOLON start
9115796c8dcSSimon Schubert { $$.start = $4;
9125796c8dcSSimon Schubert if ($1.fn.comp) { $$.last = $1.fn.last; *$1.last = $1.fn.comp; }
9135796c8dcSSimon Schubert if ($1.fold_flag)
9145796c8dcSSimon Schubert {
9155796c8dcSSimon Schubert *$$.last = $2.comp;
9165796c8dcSSimon Schubert $$.last = $2.last;
9175796c8dcSSimon Schubert }
9185796c8dcSSimon Schubert else
9195796c8dcSSimon Schubert $$.fn = $2;
9205796c8dcSSimon Schubert }
9215796c8dcSSimon Schubert | function_arglist start_opt
9225796c8dcSSimon Schubert { $$.fn = $1;
9235796c8dcSSimon Schubert $$.start = $2;
9245796c8dcSSimon Schubert $$.comp = NULL; $$.last = NULL;
9255796c8dcSSimon Schubert }
9265796c8dcSSimon Schubert ;
9275796c8dcSSimon Schubert
9285796c8dcSSimon Schubert type : typespec_2
9295796c8dcSSimon Schubert | typespec_2 abstract_declarator
9305796c8dcSSimon Schubert { $$ = $2.comp;
9315796c8dcSSimon Schubert *$2.last = $1;
9325796c8dcSSimon Schubert }
9335796c8dcSSimon Schubert ;
9345796c8dcSSimon Schubert
9355796c8dcSSimon Schubert declarator : ptr_operator declarator
9365796c8dcSSimon Schubert { $$.comp = $2.comp;
9375796c8dcSSimon Schubert $$.last = $1.last;
9385796c8dcSSimon Schubert *$2.last = $1.comp; }
9395796c8dcSSimon Schubert | direct_declarator
9405796c8dcSSimon Schubert ;
9415796c8dcSSimon Schubert
9425796c8dcSSimon Schubert direct_declarator
9435796c8dcSSimon Schubert : '(' declarator ')'
9445796c8dcSSimon Schubert { $$ = $2; }
9455796c8dcSSimon Schubert | direct_declarator function_arglist
9465796c8dcSSimon Schubert { $$.comp = $1.comp;
9475796c8dcSSimon Schubert *$1.last = $2.comp;
9485796c8dcSSimon Schubert $$.last = $2.last;
9495796c8dcSSimon Schubert }
9505796c8dcSSimon Schubert | direct_declarator array_indicator
9515796c8dcSSimon Schubert { $$.comp = $1.comp;
9525796c8dcSSimon Schubert *$1.last = $2;
9535796c8dcSSimon Schubert $$.last = &d_right ($2);
9545796c8dcSSimon Schubert }
9555796c8dcSSimon Schubert | colon_ext_name
9565796c8dcSSimon Schubert { $$.comp = make_empty (DEMANGLE_COMPONENT_TYPED_NAME);
9575796c8dcSSimon Schubert d_left ($$.comp) = $1;
9585796c8dcSSimon Schubert $$.last = &d_right ($$.comp);
9595796c8dcSSimon Schubert }
9605796c8dcSSimon Schubert ;
9615796c8dcSSimon Schubert
9625796c8dcSSimon Schubert /* These are similar to declarator and direct_declarator except that they
9635796c8dcSSimon Schubert do not permit ( colon_ext_name ), which is ambiguous with a function
9645796c8dcSSimon Schubert argument list. They also don't permit a few other forms with redundant
9655796c8dcSSimon Schubert parentheses around the colon_ext_name; any colon_ext_name in parentheses
9665796c8dcSSimon Schubert must be followed by an argument list or an array indicator, or preceded
9675796c8dcSSimon Schubert by a pointer. */
9685796c8dcSSimon Schubert declarator_1 : ptr_operator declarator_1
9695796c8dcSSimon Schubert { $$.comp = $2.comp;
9705796c8dcSSimon Schubert $$.last = $1.last;
9715796c8dcSSimon Schubert *$2.last = $1.comp; }
9725796c8dcSSimon Schubert | colon_ext_name
9735796c8dcSSimon Schubert { $$.comp = make_empty (DEMANGLE_COMPONENT_TYPED_NAME);
9745796c8dcSSimon Schubert d_left ($$.comp) = $1;
9755796c8dcSSimon Schubert $$.last = &d_right ($$.comp);
9765796c8dcSSimon Schubert }
9775796c8dcSSimon Schubert | direct_declarator_1
9785796c8dcSSimon Schubert
9795796c8dcSSimon Schubert /* Function local variable or type. The typespec to
9805796c8dcSSimon Schubert our left is the type of the containing function.
9815796c8dcSSimon Schubert This should be OK, because function local types
9825796c8dcSSimon Schubert can not be templates, so the return types of their
9835796c8dcSSimon Schubert members will not be mangled. If they are hopefully
9845796c8dcSSimon Schubert they'll end up to the right of the ::. */
9855796c8dcSSimon Schubert | colon_ext_name function_arglist COLONCOLON start
9865796c8dcSSimon Schubert { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
9875796c8dcSSimon Schubert $$.last = $2.last;
9885796c8dcSSimon Schubert $$.comp = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$.comp, $4);
9895796c8dcSSimon Schubert }
9905796c8dcSSimon Schubert | direct_declarator_1 function_arglist COLONCOLON start
9915796c8dcSSimon Schubert { $$.comp = $1.comp;
9925796c8dcSSimon Schubert *$1.last = $2.comp;
9935796c8dcSSimon Schubert $$.last = $2.last;
9945796c8dcSSimon Schubert $$.comp = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$.comp, $4);
9955796c8dcSSimon Schubert }
9965796c8dcSSimon Schubert ;
9975796c8dcSSimon Schubert
9985796c8dcSSimon Schubert direct_declarator_1
9995796c8dcSSimon Schubert : '(' ptr_operator declarator ')'
10005796c8dcSSimon Schubert { $$.comp = $3.comp;
10015796c8dcSSimon Schubert $$.last = $2.last;
10025796c8dcSSimon Schubert *$3.last = $2.comp; }
10035796c8dcSSimon Schubert | direct_declarator_1 function_arglist
10045796c8dcSSimon Schubert { $$.comp = $1.comp;
10055796c8dcSSimon Schubert *$1.last = $2.comp;
10065796c8dcSSimon Schubert $$.last = $2.last;
10075796c8dcSSimon Schubert }
10085796c8dcSSimon Schubert | direct_declarator_1 array_indicator
10095796c8dcSSimon Schubert { $$.comp = $1.comp;
10105796c8dcSSimon Schubert *$1.last = $2;
10115796c8dcSSimon Schubert $$.last = &d_right ($2);
10125796c8dcSSimon Schubert }
10135796c8dcSSimon Schubert | colon_ext_name function_arglist
10145796c8dcSSimon Schubert { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
10155796c8dcSSimon Schubert $$.last = $2.last;
10165796c8dcSSimon Schubert }
10175796c8dcSSimon Schubert | colon_ext_name array_indicator
10185796c8dcSSimon Schubert { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2);
10195796c8dcSSimon Schubert $$.last = &d_right ($2);
10205796c8dcSSimon Schubert }
10215796c8dcSSimon Schubert ;
10225796c8dcSSimon Schubert
10235796c8dcSSimon Schubert exp : '(' exp1 ')'
10245796c8dcSSimon Schubert { $$ = $2; }
10255796c8dcSSimon Schubert ;
10265796c8dcSSimon Schubert
10275796c8dcSSimon Schubert /* Silly trick. Only allow '>' when parenthesized, in order to
10285796c8dcSSimon Schubert handle conflict with templates. */
10295796c8dcSSimon Schubert exp1 : exp
10305796c8dcSSimon Schubert ;
10315796c8dcSSimon Schubert
10325796c8dcSSimon Schubert exp1 : exp '>' exp
10335796c8dcSSimon Schubert { $$ = d_binary (">", $1, $3); }
10345796c8dcSSimon Schubert ;
10355796c8dcSSimon Schubert
10365796c8dcSSimon Schubert /* References. Not allowed everywhere in template parameters, only
10375796c8dcSSimon Schubert at the top level, but treat them as expressions in case they are wrapped
10385796c8dcSSimon Schubert in parentheses. */
10395796c8dcSSimon Schubert exp1 : '&' start
10405796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $2); }
10415796c8dcSSimon Schubert | '&' '(' start ')'
10425796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $3); }
10435796c8dcSSimon Schubert ;
10445796c8dcSSimon Schubert
10455796c8dcSSimon Schubert /* Expressions, not including the comma operator. */
10465796c8dcSSimon Schubert exp : '-' exp %prec UNARY
10475796c8dcSSimon Schubert { $$ = d_unary ("-", $2); }
10485796c8dcSSimon Schubert ;
10495796c8dcSSimon Schubert
10505796c8dcSSimon Schubert exp : '!' exp %prec UNARY
10515796c8dcSSimon Schubert { $$ = d_unary ("!", $2); }
10525796c8dcSSimon Schubert ;
10535796c8dcSSimon Schubert
10545796c8dcSSimon Schubert exp : '~' exp %prec UNARY
10555796c8dcSSimon Schubert { $$ = d_unary ("~", $2); }
10565796c8dcSSimon Schubert ;
10575796c8dcSSimon Schubert
10585796c8dcSSimon Schubert /* Casts. First your normal C-style cast. If exp is a LITERAL, just change
10595796c8dcSSimon Schubert its type. */
10605796c8dcSSimon Schubert
10615796c8dcSSimon Schubert exp : '(' type ')' exp %prec UNARY
10625796c8dcSSimon Schubert { if ($4->type == DEMANGLE_COMPONENT_LITERAL
10635796c8dcSSimon Schubert || $4->type == DEMANGLE_COMPONENT_LITERAL_NEG)
10645796c8dcSSimon Schubert {
10655796c8dcSSimon Schubert $$ = $4;
10665796c8dcSSimon Schubert d_left ($4) = $2;
10675796c8dcSSimon Schubert }
10685796c8dcSSimon Schubert else
10695796c8dcSSimon Schubert $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
10705796c8dcSSimon Schubert fill_comp (DEMANGLE_COMPONENT_CAST, $2, NULL),
10715796c8dcSSimon Schubert $4);
10725796c8dcSSimon Schubert }
10735796c8dcSSimon Schubert ;
10745796c8dcSSimon Schubert
10755796c8dcSSimon Schubert /* Mangling does not differentiate between these, so we don't need to
10765796c8dcSSimon Schubert either. */
10775796c8dcSSimon Schubert exp : STATIC_CAST '<' type '>' '(' exp1 ')' %prec UNARY
10785796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
10795796c8dcSSimon Schubert fill_comp (DEMANGLE_COMPONENT_CAST, $3, NULL),
10805796c8dcSSimon Schubert $6);
10815796c8dcSSimon Schubert }
10825796c8dcSSimon Schubert ;
10835796c8dcSSimon Schubert
10845796c8dcSSimon Schubert exp : DYNAMIC_CAST '<' type '>' '(' exp1 ')' %prec UNARY
10855796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
10865796c8dcSSimon Schubert fill_comp (DEMANGLE_COMPONENT_CAST, $3, NULL),
10875796c8dcSSimon Schubert $6);
10885796c8dcSSimon Schubert }
10895796c8dcSSimon Schubert ;
10905796c8dcSSimon Schubert
10915796c8dcSSimon Schubert exp : REINTERPRET_CAST '<' type '>' '(' exp1 ')' %prec UNARY
10925796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
10935796c8dcSSimon Schubert fill_comp (DEMANGLE_COMPONENT_CAST, $3, NULL),
10945796c8dcSSimon Schubert $6);
10955796c8dcSSimon Schubert }
10965796c8dcSSimon Schubert ;
10975796c8dcSSimon Schubert
10985796c8dcSSimon Schubert /* Another form of C++-style cast is "type ( exp1 )". This creates too many
10995796c8dcSSimon Schubert conflicts to support. For a while we supported the simpler
11005796c8dcSSimon Schubert "typespec_2 ( exp1 )", but that conflicts with "& ( start )" as a
11015796c8dcSSimon Schubert reference, deep within the wilderness of abstract declarators:
11025796c8dcSSimon Schubert Qux<int(&(*))> vs Qux<int(&(var))>, a shift-reduce conflict at the
11035796c8dcSSimon Schubert innermost left parenthesis. So we do not support function-like casts.
11045796c8dcSSimon Schubert Fortunately they never appear in demangler output. */
11055796c8dcSSimon Schubert
11065796c8dcSSimon Schubert /* TO INVESTIGATE: ._0 style anonymous names; anonymous namespaces */
11075796c8dcSSimon Schubert
11085796c8dcSSimon Schubert /* Binary operators in order of decreasing precedence. */
11095796c8dcSSimon Schubert
11105796c8dcSSimon Schubert exp : exp '*' exp
11115796c8dcSSimon Schubert { $$ = d_binary ("*", $1, $3); }
11125796c8dcSSimon Schubert ;
11135796c8dcSSimon Schubert
11145796c8dcSSimon Schubert exp : exp '/' exp
11155796c8dcSSimon Schubert { $$ = d_binary ("/", $1, $3); }
11165796c8dcSSimon Schubert ;
11175796c8dcSSimon Schubert
11185796c8dcSSimon Schubert exp : exp '%' exp
11195796c8dcSSimon Schubert { $$ = d_binary ("%", $1, $3); }
11205796c8dcSSimon Schubert ;
11215796c8dcSSimon Schubert
11225796c8dcSSimon Schubert exp : exp '+' exp
11235796c8dcSSimon Schubert { $$ = d_binary ("+", $1, $3); }
11245796c8dcSSimon Schubert ;
11255796c8dcSSimon Schubert
11265796c8dcSSimon Schubert exp : exp '-' exp
11275796c8dcSSimon Schubert { $$ = d_binary ("-", $1, $3); }
11285796c8dcSSimon Schubert ;
11295796c8dcSSimon Schubert
11305796c8dcSSimon Schubert exp : exp LSH exp
11315796c8dcSSimon Schubert { $$ = d_binary ("<<", $1, $3); }
11325796c8dcSSimon Schubert ;
11335796c8dcSSimon Schubert
11345796c8dcSSimon Schubert exp : exp RSH exp
11355796c8dcSSimon Schubert { $$ = d_binary (">>", $1, $3); }
11365796c8dcSSimon Schubert ;
11375796c8dcSSimon Schubert
11385796c8dcSSimon Schubert exp : exp EQUAL exp
11395796c8dcSSimon Schubert { $$ = d_binary ("==", $1, $3); }
11405796c8dcSSimon Schubert ;
11415796c8dcSSimon Schubert
11425796c8dcSSimon Schubert exp : exp NOTEQUAL exp
11435796c8dcSSimon Schubert { $$ = d_binary ("!=", $1, $3); }
11445796c8dcSSimon Schubert ;
11455796c8dcSSimon Schubert
11465796c8dcSSimon Schubert exp : exp LEQ exp
11475796c8dcSSimon Schubert { $$ = d_binary ("<=", $1, $3); }
11485796c8dcSSimon Schubert ;
11495796c8dcSSimon Schubert
11505796c8dcSSimon Schubert exp : exp GEQ exp
11515796c8dcSSimon Schubert { $$ = d_binary (">=", $1, $3); }
11525796c8dcSSimon Schubert ;
11535796c8dcSSimon Schubert
11545796c8dcSSimon Schubert exp : exp '<' exp
11555796c8dcSSimon Schubert { $$ = d_binary ("<", $1, $3); }
11565796c8dcSSimon Schubert ;
11575796c8dcSSimon Schubert
11585796c8dcSSimon Schubert exp : exp '&' exp
11595796c8dcSSimon Schubert { $$ = d_binary ("&", $1, $3); }
11605796c8dcSSimon Schubert ;
11615796c8dcSSimon Schubert
11625796c8dcSSimon Schubert exp : exp '^' exp
11635796c8dcSSimon Schubert { $$ = d_binary ("^", $1, $3); }
11645796c8dcSSimon Schubert ;
11655796c8dcSSimon Schubert
11665796c8dcSSimon Schubert exp : exp '|' exp
11675796c8dcSSimon Schubert { $$ = d_binary ("|", $1, $3); }
11685796c8dcSSimon Schubert ;
11695796c8dcSSimon Schubert
11705796c8dcSSimon Schubert exp : exp ANDAND exp
11715796c8dcSSimon Schubert { $$ = d_binary ("&&", $1, $3); }
11725796c8dcSSimon Schubert ;
11735796c8dcSSimon Schubert
11745796c8dcSSimon Schubert exp : exp OROR exp
11755796c8dcSSimon Schubert { $$ = d_binary ("||", $1, $3); }
11765796c8dcSSimon Schubert ;
11775796c8dcSSimon Schubert
11785796c8dcSSimon Schubert /* Not 100% sure these are necessary, but they're harmless. */
11795796c8dcSSimon Schubert exp : exp ARROW NAME
11805796c8dcSSimon Schubert { $$ = d_binary ("->", $1, $3); }
11815796c8dcSSimon Schubert ;
11825796c8dcSSimon Schubert
11835796c8dcSSimon Schubert exp : exp '.' NAME
11845796c8dcSSimon Schubert { $$ = d_binary (".", $1, $3); }
11855796c8dcSSimon Schubert ;
11865796c8dcSSimon Schubert
11875796c8dcSSimon Schubert exp : exp '?' exp ':' exp %prec '?'
11885796c8dcSSimon Schubert { $$ = fill_comp (DEMANGLE_COMPONENT_TRINARY, make_operator ("?", 3),
11895796c8dcSSimon Schubert fill_comp (DEMANGLE_COMPONENT_TRINARY_ARG1, $1,
11905796c8dcSSimon Schubert fill_comp (DEMANGLE_COMPONENT_TRINARY_ARG2, $3, $5)));
11915796c8dcSSimon Schubert }
11925796c8dcSSimon Schubert ;
11935796c8dcSSimon Schubert
11945796c8dcSSimon Schubert exp : INT
11955796c8dcSSimon Schubert ;
11965796c8dcSSimon Schubert
11975796c8dcSSimon Schubert /* Not generally allowed. */
11985796c8dcSSimon Schubert exp : FLOAT
11995796c8dcSSimon Schubert ;
12005796c8dcSSimon Schubert
12015796c8dcSSimon Schubert exp : SIZEOF '(' type ')' %prec UNARY
1202*ef5ccd6cSJohn Marino {
1203*ef5ccd6cSJohn Marino /* Match the whitespacing of cplus_demangle_operators.
1204*ef5ccd6cSJohn Marino It would abort on unrecognized string otherwise. */
1205*ef5ccd6cSJohn Marino $$ = d_unary ("sizeof ", $3);
1206*ef5ccd6cSJohn Marino }
12075796c8dcSSimon Schubert ;
12085796c8dcSSimon Schubert
12095796c8dcSSimon Schubert /* C++. */
12105796c8dcSSimon Schubert exp : TRUEKEYWORD
12115796c8dcSSimon Schubert { struct demangle_component *i;
12125796c8dcSSimon Schubert i = make_name ("1", 1);
12135796c8dcSSimon Schubert $$ = fill_comp (DEMANGLE_COMPONENT_LITERAL,
12145796c8dcSSimon Schubert make_builtin_type ("bool"),
12155796c8dcSSimon Schubert i);
12165796c8dcSSimon Schubert }
12175796c8dcSSimon Schubert ;
12185796c8dcSSimon Schubert
12195796c8dcSSimon Schubert exp : FALSEKEYWORD
12205796c8dcSSimon Schubert { struct demangle_component *i;
12215796c8dcSSimon Schubert i = make_name ("0", 1);
12225796c8dcSSimon Schubert $$ = fill_comp (DEMANGLE_COMPONENT_LITERAL,
12235796c8dcSSimon Schubert make_builtin_type ("bool"),
12245796c8dcSSimon Schubert i);
12255796c8dcSSimon Schubert }
12265796c8dcSSimon Schubert ;
12275796c8dcSSimon Schubert
12285796c8dcSSimon Schubert /* end of C++. */
12295796c8dcSSimon Schubert
12305796c8dcSSimon Schubert %%
12315796c8dcSSimon Schubert
12325796c8dcSSimon Schubert /* Apply QUALIFIERS to LHS and return a qualified component. IS_METHOD
12335796c8dcSSimon Schubert is set if LHS is a method, in which case the qualifiers are logically
12345796c8dcSSimon Schubert applied to "this". We apply qualifiers in a consistent order; LHS
12355796c8dcSSimon Schubert may already be qualified; duplicate qualifiers are not created. */
12365796c8dcSSimon Schubert
12375796c8dcSSimon Schubert struct demangle_component *
12385796c8dcSSimon Schubert d_qualify (struct demangle_component *lhs, int qualifiers, int is_method)
12395796c8dcSSimon Schubert {
12405796c8dcSSimon Schubert struct demangle_component **inner_p;
12415796c8dcSSimon Schubert enum demangle_component_type type;
12425796c8dcSSimon Schubert
12435796c8dcSSimon Schubert /* For now the order is CONST (innermost), VOLATILE, RESTRICT. */
12445796c8dcSSimon Schubert
12455796c8dcSSimon Schubert #define HANDLE_QUAL(TYPE, MTYPE, QUAL) \
12465796c8dcSSimon Schubert if ((qualifiers & QUAL) && (type != TYPE) && (type != MTYPE)) \
12475796c8dcSSimon Schubert { \
12485796c8dcSSimon Schubert *inner_p = fill_comp (is_method ? MTYPE : TYPE, \
12495796c8dcSSimon Schubert *inner_p, NULL); \
12505796c8dcSSimon Schubert inner_p = &d_left (*inner_p); \
12515796c8dcSSimon Schubert type = (*inner_p)->type; \
12525796c8dcSSimon Schubert } \
12535796c8dcSSimon Schubert else if (type == TYPE || type == MTYPE) \
12545796c8dcSSimon Schubert { \
12555796c8dcSSimon Schubert inner_p = &d_left (*inner_p); \
12565796c8dcSSimon Schubert type = (*inner_p)->type; \
12575796c8dcSSimon Schubert }
12585796c8dcSSimon Schubert
12595796c8dcSSimon Schubert inner_p = &lhs;
12605796c8dcSSimon Schubert
12615796c8dcSSimon Schubert type = (*inner_p)->type;
12625796c8dcSSimon Schubert
12635796c8dcSSimon Schubert HANDLE_QUAL (DEMANGLE_COMPONENT_RESTRICT, DEMANGLE_COMPONENT_RESTRICT_THIS, QUAL_RESTRICT);
12645796c8dcSSimon Schubert HANDLE_QUAL (DEMANGLE_COMPONENT_VOLATILE, DEMANGLE_COMPONENT_VOLATILE_THIS, QUAL_VOLATILE);
12655796c8dcSSimon Schubert HANDLE_QUAL (DEMANGLE_COMPONENT_CONST, DEMANGLE_COMPONENT_CONST_THIS, QUAL_CONST);
12665796c8dcSSimon Schubert
12675796c8dcSSimon Schubert return lhs;
12685796c8dcSSimon Schubert }
12695796c8dcSSimon Schubert
12705796c8dcSSimon Schubert /* Return a builtin type corresponding to FLAGS. */
12715796c8dcSSimon Schubert
12725796c8dcSSimon Schubert static struct demangle_component *
d_int_type(int flags)12735796c8dcSSimon Schubert d_int_type (int flags)
12745796c8dcSSimon Schubert {
12755796c8dcSSimon Schubert const char *name;
12765796c8dcSSimon Schubert
12775796c8dcSSimon Schubert switch (flags)
12785796c8dcSSimon Schubert {
12795796c8dcSSimon Schubert case INT_SIGNED | INT_CHAR:
12805796c8dcSSimon Schubert name = "signed char";
12815796c8dcSSimon Schubert break;
12825796c8dcSSimon Schubert case INT_CHAR:
12835796c8dcSSimon Schubert name = "char";
12845796c8dcSSimon Schubert break;
12855796c8dcSSimon Schubert case INT_UNSIGNED | INT_CHAR:
12865796c8dcSSimon Schubert name = "unsigned char";
12875796c8dcSSimon Schubert break;
12885796c8dcSSimon Schubert case 0:
12895796c8dcSSimon Schubert case INT_SIGNED:
12905796c8dcSSimon Schubert name = "int";
12915796c8dcSSimon Schubert break;
12925796c8dcSSimon Schubert case INT_UNSIGNED:
12935796c8dcSSimon Schubert name = "unsigned int";
12945796c8dcSSimon Schubert break;
12955796c8dcSSimon Schubert case INT_LONG:
12965796c8dcSSimon Schubert case INT_SIGNED | INT_LONG:
12975796c8dcSSimon Schubert name = "long";
12985796c8dcSSimon Schubert break;
12995796c8dcSSimon Schubert case INT_UNSIGNED | INT_LONG:
13005796c8dcSSimon Schubert name = "unsigned long";
13015796c8dcSSimon Schubert break;
13025796c8dcSSimon Schubert case INT_SHORT:
13035796c8dcSSimon Schubert case INT_SIGNED | INT_SHORT:
13045796c8dcSSimon Schubert name = "short";
13055796c8dcSSimon Schubert break;
13065796c8dcSSimon Schubert case INT_UNSIGNED | INT_SHORT:
13075796c8dcSSimon Schubert name = "unsigned short";
13085796c8dcSSimon Schubert break;
13095796c8dcSSimon Schubert case INT_LLONG | INT_LONG:
13105796c8dcSSimon Schubert case INT_SIGNED | INT_LLONG | INT_LONG:
13115796c8dcSSimon Schubert name = "long long";
13125796c8dcSSimon Schubert break;
13135796c8dcSSimon Schubert case INT_UNSIGNED | INT_LLONG | INT_LONG:
13145796c8dcSSimon Schubert name = "unsigned long long";
13155796c8dcSSimon Schubert break;
13165796c8dcSSimon Schubert default:
13175796c8dcSSimon Schubert return NULL;
13185796c8dcSSimon Schubert }
13195796c8dcSSimon Schubert
13205796c8dcSSimon Schubert return make_builtin_type (name);
13215796c8dcSSimon Schubert }
13225796c8dcSSimon Schubert
13235796c8dcSSimon Schubert /* Wrapper to create a unary operation. */
13245796c8dcSSimon Schubert
13255796c8dcSSimon Schubert static struct demangle_component *
d_unary(const char * name,struct demangle_component * lhs)13265796c8dcSSimon Schubert d_unary (const char *name, struct demangle_component *lhs)
13275796c8dcSSimon Schubert {
13285796c8dcSSimon Schubert return fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator (name, 1), lhs);
13295796c8dcSSimon Schubert }
13305796c8dcSSimon Schubert
13315796c8dcSSimon Schubert /* Wrapper to create a binary operation. */
13325796c8dcSSimon Schubert
13335796c8dcSSimon Schubert static struct demangle_component *
d_binary(const char * name,struct demangle_component * lhs,struct demangle_component * rhs)13345796c8dcSSimon Schubert d_binary (const char *name, struct demangle_component *lhs, struct demangle_component *rhs)
13355796c8dcSSimon Schubert {
13365796c8dcSSimon Schubert return fill_comp (DEMANGLE_COMPONENT_BINARY, make_operator (name, 2),
13375796c8dcSSimon Schubert fill_comp (DEMANGLE_COMPONENT_BINARY_ARGS, lhs, rhs));
13385796c8dcSSimon Schubert }
13395796c8dcSSimon Schubert
13405796c8dcSSimon Schubert /* Find the end of a symbol name starting at LEXPTR. */
13415796c8dcSSimon Schubert
13425796c8dcSSimon Schubert static const char *
symbol_end(const char * lexptr)13435796c8dcSSimon Schubert symbol_end (const char *lexptr)
13445796c8dcSSimon Schubert {
13455796c8dcSSimon Schubert const char *p = lexptr;
13465796c8dcSSimon Schubert
13475796c8dcSSimon Schubert while (*p && (ISALNUM (*p) || *p == '_' || *p == '$' || *p == '.'))
13485796c8dcSSimon Schubert p++;
13495796c8dcSSimon Schubert
13505796c8dcSSimon Schubert return p;
13515796c8dcSSimon Schubert }
13525796c8dcSSimon Schubert
13535796c8dcSSimon Schubert /* Take care of parsing a number (anything that starts with a digit).
13545796c8dcSSimon Schubert The number starts at P and contains LEN characters. Store the result in
13555796c8dcSSimon Schubert YYLVAL. */
13565796c8dcSSimon Schubert
13575796c8dcSSimon Schubert static int
parse_number(const char * p,int len,int parsed_float)13585796c8dcSSimon Schubert parse_number (const char *p, int len, int parsed_float)
13595796c8dcSSimon Schubert {
13605796c8dcSSimon Schubert int unsigned_p = 0;
13615796c8dcSSimon Schubert
13625796c8dcSSimon Schubert /* Number of "L" suffixes encountered. */
13635796c8dcSSimon Schubert int long_p = 0;
13645796c8dcSSimon Schubert
13655796c8dcSSimon Schubert struct demangle_component *signed_type;
13665796c8dcSSimon Schubert struct demangle_component *unsigned_type;
13675796c8dcSSimon Schubert struct demangle_component *type, *name;
13685796c8dcSSimon Schubert enum demangle_component_type literal_type;
13695796c8dcSSimon Schubert
13705796c8dcSSimon Schubert if (p[0] == '-')
13715796c8dcSSimon Schubert {
13725796c8dcSSimon Schubert literal_type = DEMANGLE_COMPONENT_LITERAL_NEG;
13735796c8dcSSimon Schubert p++;
13745796c8dcSSimon Schubert len--;
13755796c8dcSSimon Schubert }
13765796c8dcSSimon Schubert else
13775796c8dcSSimon Schubert literal_type = DEMANGLE_COMPONENT_LITERAL;
13785796c8dcSSimon Schubert
13795796c8dcSSimon Schubert if (parsed_float)
13805796c8dcSSimon Schubert {
13815796c8dcSSimon Schubert /* It's a float since it contains a point or an exponent. */
13825796c8dcSSimon Schubert char c;
13835796c8dcSSimon Schubert
13845796c8dcSSimon Schubert /* The GDB lexer checks the result of scanf at this point. Not doing
13855796c8dcSSimon Schubert this leaves our error checking slightly weaker but only for invalid
13865796c8dcSSimon Schubert data. */
13875796c8dcSSimon Schubert
13885796c8dcSSimon Schubert /* See if it has `f' or `l' suffix (float or long double). */
13895796c8dcSSimon Schubert
13905796c8dcSSimon Schubert c = TOLOWER (p[len - 1]);
13915796c8dcSSimon Schubert
13925796c8dcSSimon Schubert if (c == 'f')
13935796c8dcSSimon Schubert {
13945796c8dcSSimon Schubert len--;
13955796c8dcSSimon Schubert type = make_builtin_type ("float");
13965796c8dcSSimon Schubert }
13975796c8dcSSimon Schubert else if (c == 'l')
13985796c8dcSSimon Schubert {
13995796c8dcSSimon Schubert len--;
14005796c8dcSSimon Schubert type = make_builtin_type ("long double");
14015796c8dcSSimon Schubert }
14025796c8dcSSimon Schubert else if (ISDIGIT (c) || c == '.')
14035796c8dcSSimon Schubert type = make_builtin_type ("double");
14045796c8dcSSimon Schubert else
14055796c8dcSSimon Schubert return ERROR;
14065796c8dcSSimon Schubert
14075796c8dcSSimon Schubert name = make_name (p, len);
14085796c8dcSSimon Schubert yylval.comp = fill_comp (literal_type, type, name);
14095796c8dcSSimon Schubert
14105796c8dcSSimon Schubert return FLOAT;
14115796c8dcSSimon Schubert }
14125796c8dcSSimon Schubert
14135796c8dcSSimon Schubert /* This treats 0x1 and 1 as different literals. We also do not
14145796c8dcSSimon Schubert automatically generate unsigned types. */
14155796c8dcSSimon Schubert
14165796c8dcSSimon Schubert long_p = 0;
14175796c8dcSSimon Schubert unsigned_p = 0;
14185796c8dcSSimon Schubert while (len > 0)
14195796c8dcSSimon Schubert {
14205796c8dcSSimon Schubert if (p[len - 1] == 'l' || p[len - 1] == 'L')
14215796c8dcSSimon Schubert {
14225796c8dcSSimon Schubert len--;
14235796c8dcSSimon Schubert long_p++;
14245796c8dcSSimon Schubert continue;
14255796c8dcSSimon Schubert }
14265796c8dcSSimon Schubert if (p[len - 1] == 'u' || p[len - 1] == 'U')
14275796c8dcSSimon Schubert {
14285796c8dcSSimon Schubert len--;
14295796c8dcSSimon Schubert unsigned_p++;
14305796c8dcSSimon Schubert continue;
14315796c8dcSSimon Schubert }
14325796c8dcSSimon Schubert break;
14335796c8dcSSimon Schubert }
14345796c8dcSSimon Schubert
14355796c8dcSSimon Schubert if (long_p == 0)
14365796c8dcSSimon Schubert {
14375796c8dcSSimon Schubert unsigned_type = make_builtin_type ("unsigned int");
14385796c8dcSSimon Schubert signed_type = make_builtin_type ("int");
14395796c8dcSSimon Schubert }
14405796c8dcSSimon Schubert else if (long_p == 1)
14415796c8dcSSimon Schubert {
14425796c8dcSSimon Schubert unsigned_type = make_builtin_type ("unsigned long");
14435796c8dcSSimon Schubert signed_type = make_builtin_type ("long");
14445796c8dcSSimon Schubert }
14455796c8dcSSimon Schubert else
14465796c8dcSSimon Schubert {
14475796c8dcSSimon Schubert unsigned_type = make_builtin_type ("unsigned long long");
14485796c8dcSSimon Schubert signed_type = make_builtin_type ("long long");
14495796c8dcSSimon Schubert }
14505796c8dcSSimon Schubert
14515796c8dcSSimon Schubert if (unsigned_p)
14525796c8dcSSimon Schubert type = unsigned_type;
14535796c8dcSSimon Schubert else
14545796c8dcSSimon Schubert type = signed_type;
14555796c8dcSSimon Schubert
14565796c8dcSSimon Schubert name = make_name (p, len);
14575796c8dcSSimon Schubert yylval.comp = fill_comp (literal_type, type, name);
14585796c8dcSSimon Schubert
14595796c8dcSSimon Schubert return INT;
14605796c8dcSSimon Schubert }
14615796c8dcSSimon Schubert
14625796c8dcSSimon Schubert static char backslashable[] = "abefnrtv";
14635796c8dcSSimon Schubert static char represented[] = "\a\b\e\f\n\r\t\v";
14645796c8dcSSimon Schubert
14655796c8dcSSimon Schubert /* Translate the backslash the way we would in the host character set. */
14665796c8dcSSimon Schubert static int
c_parse_backslash(int host_char,int * target_char)14675796c8dcSSimon Schubert c_parse_backslash (int host_char, int *target_char)
14685796c8dcSSimon Schubert {
14695796c8dcSSimon Schubert const char *ix;
14705796c8dcSSimon Schubert ix = strchr (backslashable, host_char);
14715796c8dcSSimon Schubert if (! ix)
14725796c8dcSSimon Schubert return 0;
14735796c8dcSSimon Schubert else
14745796c8dcSSimon Schubert *target_char = represented[ix - backslashable];
14755796c8dcSSimon Schubert return 1;
14765796c8dcSSimon Schubert }
14775796c8dcSSimon Schubert
14785796c8dcSSimon Schubert /* Parse a C escape sequence. STRING_PTR points to a variable
14795796c8dcSSimon Schubert containing a pointer to the string to parse. That pointer
14805796c8dcSSimon Schubert should point to the character after the \. That pointer
14815796c8dcSSimon Schubert is updated past the characters we use. The value of the
14825796c8dcSSimon Schubert escape sequence is returned.
14835796c8dcSSimon Schubert
14845796c8dcSSimon Schubert A negative value means the sequence \ newline was seen,
14855796c8dcSSimon Schubert which is supposed to be equivalent to nothing at all.
14865796c8dcSSimon Schubert
14875796c8dcSSimon Schubert If \ is followed by a null character, we return a negative
14885796c8dcSSimon Schubert value and leave the string pointer pointing at the null character.
14895796c8dcSSimon Schubert
14905796c8dcSSimon Schubert If \ is followed by 000, we return 0 and leave the string pointer
14915796c8dcSSimon Schubert after the zeros. A value of 0 does not mean end of string. */
14925796c8dcSSimon Schubert
14935796c8dcSSimon Schubert static int
cp_parse_escape(const char ** string_ptr)14945796c8dcSSimon Schubert cp_parse_escape (const char **string_ptr)
14955796c8dcSSimon Schubert {
14965796c8dcSSimon Schubert int target_char;
14975796c8dcSSimon Schubert int c = *(*string_ptr)++;
14985796c8dcSSimon Schubert if (c_parse_backslash (c, &target_char))
14995796c8dcSSimon Schubert return target_char;
15005796c8dcSSimon Schubert else
15015796c8dcSSimon Schubert switch (c)
15025796c8dcSSimon Schubert {
15035796c8dcSSimon Schubert case '\n':
15045796c8dcSSimon Schubert return -2;
15055796c8dcSSimon Schubert case 0:
15065796c8dcSSimon Schubert (*string_ptr)--;
15075796c8dcSSimon Schubert return 0;
15085796c8dcSSimon Schubert case '^':
15095796c8dcSSimon Schubert {
15105796c8dcSSimon Schubert c = *(*string_ptr)++;
15115796c8dcSSimon Schubert
15125796c8dcSSimon Schubert if (c == '?')
15135796c8dcSSimon Schubert return 0177;
15145796c8dcSSimon Schubert else if (c == '\\')
15155796c8dcSSimon Schubert target_char = cp_parse_escape (string_ptr);
15165796c8dcSSimon Schubert else
15175796c8dcSSimon Schubert target_char = c;
15185796c8dcSSimon Schubert
15195796c8dcSSimon Schubert /* Now target_char is something like `c', and we want to find
15205796c8dcSSimon Schubert its control-character equivalent. */
15215796c8dcSSimon Schubert target_char = target_char & 037;
15225796c8dcSSimon Schubert
15235796c8dcSSimon Schubert return target_char;
15245796c8dcSSimon Schubert }
15255796c8dcSSimon Schubert
15265796c8dcSSimon Schubert case '0':
15275796c8dcSSimon Schubert case '1':
15285796c8dcSSimon Schubert case '2':
15295796c8dcSSimon Schubert case '3':
15305796c8dcSSimon Schubert case '4':
15315796c8dcSSimon Schubert case '5':
15325796c8dcSSimon Schubert case '6':
15335796c8dcSSimon Schubert case '7':
15345796c8dcSSimon Schubert {
15355796c8dcSSimon Schubert int i = c - '0';
15365796c8dcSSimon Schubert int count = 0;
15375796c8dcSSimon Schubert while (++count < 3)
15385796c8dcSSimon Schubert {
15395796c8dcSSimon Schubert c = (**string_ptr);
15405796c8dcSSimon Schubert if (c >= '0' && c <= '7')
15415796c8dcSSimon Schubert {
15425796c8dcSSimon Schubert (*string_ptr)++;
15435796c8dcSSimon Schubert i *= 8;
15445796c8dcSSimon Schubert i += c - '0';
15455796c8dcSSimon Schubert }
15465796c8dcSSimon Schubert else
15475796c8dcSSimon Schubert {
15485796c8dcSSimon Schubert break;
15495796c8dcSSimon Schubert }
15505796c8dcSSimon Schubert }
15515796c8dcSSimon Schubert return i;
15525796c8dcSSimon Schubert }
15535796c8dcSSimon Schubert default:
15545796c8dcSSimon Schubert return c;
15555796c8dcSSimon Schubert }
15565796c8dcSSimon Schubert }
15575796c8dcSSimon Schubert
15585796c8dcSSimon Schubert #define HANDLE_SPECIAL(string, comp) \
15595796c8dcSSimon Schubert if (strncmp (tokstart, string, sizeof (string) - 1) == 0) \
15605796c8dcSSimon Schubert { \
15615796c8dcSSimon Schubert lexptr = tokstart + sizeof (string) - 1; \
15625796c8dcSSimon Schubert yylval.lval = comp; \
15635796c8dcSSimon Schubert return DEMANGLER_SPECIAL; \
15645796c8dcSSimon Schubert }
15655796c8dcSSimon Schubert
15665796c8dcSSimon Schubert #define HANDLE_TOKEN2(string, token) \
15675796c8dcSSimon Schubert if (lexptr[1] == string[1]) \
15685796c8dcSSimon Schubert { \
15695796c8dcSSimon Schubert lexptr += 2; \
15705796c8dcSSimon Schubert yylval.opname = string; \
15715796c8dcSSimon Schubert return token; \
15725796c8dcSSimon Schubert }
15735796c8dcSSimon Schubert
15745796c8dcSSimon Schubert #define HANDLE_TOKEN3(string, token) \
15755796c8dcSSimon Schubert if (lexptr[1] == string[1] && lexptr[2] == string[2]) \
15765796c8dcSSimon Schubert { \
15775796c8dcSSimon Schubert lexptr += 3; \
15785796c8dcSSimon Schubert yylval.opname = string; \
15795796c8dcSSimon Schubert return token; \
15805796c8dcSSimon Schubert }
15815796c8dcSSimon Schubert
15825796c8dcSSimon Schubert /* Read one token, getting characters through LEXPTR. */
15835796c8dcSSimon Schubert
15845796c8dcSSimon Schubert static int
yylex(void)15855796c8dcSSimon Schubert yylex (void)
15865796c8dcSSimon Schubert {
15875796c8dcSSimon Schubert int c;
15885796c8dcSSimon Schubert int namelen;
1589cf7f2e2dSJohn Marino const char *tokstart;
15905796c8dcSSimon Schubert
15915796c8dcSSimon Schubert retry:
15925796c8dcSSimon Schubert prev_lexptr = lexptr;
15935796c8dcSSimon Schubert tokstart = lexptr;
15945796c8dcSSimon Schubert
15955796c8dcSSimon Schubert switch (c = *tokstart)
15965796c8dcSSimon Schubert {
15975796c8dcSSimon Schubert case 0:
15985796c8dcSSimon Schubert return 0;
15995796c8dcSSimon Schubert
16005796c8dcSSimon Schubert case ' ':
16015796c8dcSSimon Schubert case '\t':
16025796c8dcSSimon Schubert case '\n':
16035796c8dcSSimon Schubert lexptr++;
16045796c8dcSSimon Schubert goto retry;
16055796c8dcSSimon Schubert
16065796c8dcSSimon Schubert case '\'':
16075796c8dcSSimon Schubert /* We either have a character constant ('0' or '\177' for example)
16085796c8dcSSimon Schubert or we have a quoted symbol reference ('foo(int,int)' in C++
16095796c8dcSSimon Schubert for example). */
16105796c8dcSSimon Schubert lexptr++;
16115796c8dcSSimon Schubert c = *lexptr++;
16125796c8dcSSimon Schubert if (c == '\\')
16135796c8dcSSimon Schubert c = cp_parse_escape (&lexptr);
16145796c8dcSSimon Schubert else if (c == '\'')
16155796c8dcSSimon Schubert {
1616c50c785cSJohn Marino yyerror (_("empty character constant"));
16175796c8dcSSimon Schubert return ERROR;
16185796c8dcSSimon Schubert }
16195796c8dcSSimon Schubert
16205796c8dcSSimon Schubert c = *lexptr++;
16215796c8dcSSimon Schubert if (c != '\'')
16225796c8dcSSimon Schubert {
1623c50c785cSJohn Marino yyerror (_("invalid character constant"));
16245796c8dcSSimon Schubert return ERROR;
16255796c8dcSSimon Schubert }
16265796c8dcSSimon Schubert
16275796c8dcSSimon Schubert /* FIXME: We should refer to a canonical form of the character,
16285796c8dcSSimon Schubert presumably the same one that appears in manglings - the decimal
16295796c8dcSSimon Schubert representation. But if that isn't in our input then we have to
16305796c8dcSSimon Schubert allocate memory for it somewhere. */
16315796c8dcSSimon Schubert yylval.comp = fill_comp (DEMANGLE_COMPONENT_LITERAL,
16325796c8dcSSimon Schubert make_builtin_type ("char"),
16335796c8dcSSimon Schubert make_name (tokstart, lexptr - tokstart));
16345796c8dcSSimon Schubert
16355796c8dcSSimon Schubert return INT;
16365796c8dcSSimon Schubert
16375796c8dcSSimon Schubert case '(':
16385796c8dcSSimon Schubert if (strncmp (tokstart, "(anonymous namespace)", 21) == 0)
16395796c8dcSSimon Schubert {
16405796c8dcSSimon Schubert lexptr += 21;
16415796c8dcSSimon Schubert yylval.comp = make_name ("(anonymous namespace)",
16425796c8dcSSimon Schubert sizeof "(anonymous namespace)" - 1);
16435796c8dcSSimon Schubert return NAME;
16445796c8dcSSimon Schubert }
16455796c8dcSSimon Schubert /* FALL THROUGH */
16465796c8dcSSimon Schubert
16475796c8dcSSimon Schubert case ')':
16485796c8dcSSimon Schubert case ',':
16495796c8dcSSimon Schubert lexptr++;
16505796c8dcSSimon Schubert return c;
16515796c8dcSSimon Schubert
16525796c8dcSSimon Schubert case '.':
16535796c8dcSSimon Schubert if (lexptr[1] == '.' && lexptr[2] == '.')
16545796c8dcSSimon Schubert {
16555796c8dcSSimon Schubert lexptr += 3;
16565796c8dcSSimon Schubert return ELLIPSIS;
16575796c8dcSSimon Schubert }
16585796c8dcSSimon Schubert
16595796c8dcSSimon Schubert /* Might be a floating point number. */
16605796c8dcSSimon Schubert if (lexptr[1] < '0' || lexptr[1] > '9')
16615796c8dcSSimon Schubert goto symbol; /* Nope, must be a symbol. */
16625796c8dcSSimon Schubert
16635796c8dcSSimon Schubert goto try_number;
16645796c8dcSSimon Schubert
16655796c8dcSSimon Schubert case '-':
16665796c8dcSSimon Schubert HANDLE_TOKEN2 ("-=", ASSIGN_MODIFY);
16675796c8dcSSimon Schubert HANDLE_TOKEN2 ("--", DECREMENT);
16685796c8dcSSimon Schubert HANDLE_TOKEN2 ("->", ARROW);
16695796c8dcSSimon Schubert
16705796c8dcSSimon Schubert /* For construction vtables. This is kind of hokey. */
16715796c8dcSSimon Schubert if (strncmp (tokstart, "-in-", 4) == 0)
16725796c8dcSSimon Schubert {
16735796c8dcSSimon Schubert lexptr += 4;
16745796c8dcSSimon Schubert return CONSTRUCTION_IN;
16755796c8dcSSimon Schubert }
16765796c8dcSSimon Schubert
16775796c8dcSSimon Schubert if (lexptr[1] < '0' || lexptr[1] > '9')
16785796c8dcSSimon Schubert {
16795796c8dcSSimon Schubert lexptr++;
16805796c8dcSSimon Schubert return '-';
16815796c8dcSSimon Schubert }
16825796c8dcSSimon Schubert /* FALL THRU into number case. */
16835796c8dcSSimon Schubert
16845796c8dcSSimon Schubert try_number:
16855796c8dcSSimon Schubert case '0':
16865796c8dcSSimon Schubert case '1':
16875796c8dcSSimon Schubert case '2':
16885796c8dcSSimon Schubert case '3':
16895796c8dcSSimon Schubert case '4':
16905796c8dcSSimon Schubert case '5':
16915796c8dcSSimon Schubert case '6':
16925796c8dcSSimon Schubert case '7':
16935796c8dcSSimon Schubert case '8':
16945796c8dcSSimon Schubert case '9':
16955796c8dcSSimon Schubert {
16965796c8dcSSimon Schubert /* It's a number. */
16975796c8dcSSimon Schubert int got_dot = 0, got_e = 0, toktype;
16985796c8dcSSimon Schubert const char *p = tokstart;
16995796c8dcSSimon Schubert int hex = 0;
17005796c8dcSSimon Schubert
17015796c8dcSSimon Schubert if (c == '-')
17025796c8dcSSimon Schubert p++;
17035796c8dcSSimon Schubert
17045796c8dcSSimon Schubert if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
17055796c8dcSSimon Schubert {
17065796c8dcSSimon Schubert p += 2;
17075796c8dcSSimon Schubert hex = 1;
17085796c8dcSSimon Schubert }
17095796c8dcSSimon Schubert else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
17105796c8dcSSimon Schubert {
17115796c8dcSSimon Schubert p += 2;
17125796c8dcSSimon Schubert hex = 0;
17135796c8dcSSimon Schubert }
17145796c8dcSSimon Schubert
17155796c8dcSSimon Schubert for (;; ++p)
17165796c8dcSSimon Schubert {
17175796c8dcSSimon Schubert /* This test includes !hex because 'e' is a valid hex digit
17185796c8dcSSimon Schubert and thus does not indicate a floating point number when
17195796c8dcSSimon Schubert the radix is hex. */
17205796c8dcSSimon Schubert if (!hex && !got_e && (*p == 'e' || *p == 'E'))
17215796c8dcSSimon Schubert got_dot = got_e = 1;
17225796c8dcSSimon Schubert /* This test does not include !hex, because a '.' always indicates
17235796c8dcSSimon Schubert a decimal floating point number regardless of the radix.
17245796c8dcSSimon Schubert
17255796c8dcSSimon Schubert NOTE drow/2005-03-09: This comment is not accurate in C99;
17265796c8dcSSimon Schubert however, it's not clear that all the floating point support
17275796c8dcSSimon Schubert in this file is doing any good here. */
17285796c8dcSSimon Schubert else if (!got_dot && *p == '.')
17295796c8dcSSimon Schubert got_dot = 1;
17305796c8dcSSimon Schubert else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
17315796c8dcSSimon Schubert && (*p == '-' || *p == '+'))
17325796c8dcSSimon Schubert /* This is the sign of the exponent, not the end of the
17335796c8dcSSimon Schubert number. */
17345796c8dcSSimon Schubert continue;
17355796c8dcSSimon Schubert /* We will take any letters or digits. parse_number will
17365796c8dcSSimon Schubert complain if past the radix, or if L or U are not final. */
17375796c8dcSSimon Schubert else if (! ISALNUM (*p))
17385796c8dcSSimon Schubert break;
17395796c8dcSSimon Schubert }
17405796c8dcSSimon Schubert toktype = parse_number (tokstart, p - tokstart, got_dot|got_e);
17415796c8dcSSimon Schubert if (toktype == ERROR)
17425796c8dcSSimon Schubert {
17435796c8dcSSimon Schubert char *err_copy = (char *) alloca (p - tokstart + 1);
17445796c8dcSSimon Schubert
17455796c8dcSSimon Schubert memcpy (err_copy, tokstart, p - tokstart);
17465796c8dcSSimon Schubert err_copy[p - tokstart] = 0;
1747c50c785cSJohn Marino yyerror (_("invalid number"));
17485796c8dcSSimon Schubert return ERROR;
17495796c8dcSSimon Schubert }
17505796c8dcSSimon Schubert lexptr = p;
17515796c8dcSSimon Schubert return toktype;
17525796c8dcSSimon Schubert }
17535796c8dcSSimon Schubert
17545796c8dcSSimon Schubert case '+':
17555796c8dcSSimon Schubert HANDLE_TOKEN2 ("+=", ASSIGN_MODIFY);
17565796c8dcSSimon Schubert HANDLE_TOKEN2 ("++", INCREMENT);
17575796c8dcSSimon Schubert lexptr++;
17585796c8dcSSimon Schubert return c;
17595796c8dcSSimon Schubert case '*':
17605796c8dcSSimon Schubert HANDLE_TOKEN2 ("*=", ASSIGN_MODIFY);
17615796c8dcSSimon Schubert lexptr++;
17625796c8dcSSimon Schubert return c;
17635796c8dcSSimon Schubert case '/':
17645796c8dcSSimon Schubert HANDLE_TOKEN2 ("/=", ASSIGN_MODIFY);
17655796c8dcSSimon Schubert lexptr++;
17665796c8dcSSimon Schubert return c;
17675796c8dcSSimon Schubert case '%':
17685796c8dcSSimon Schubert HANDLE_TOKEN2 ("%=", ASSIGN_MODIFY);
17695796c8dcSSimon Schubert lexptr++;
17705796c8dcSSimon Schubert return c;
17715796c8dcSSimon Schubert case '|':
17725796c8dcSSimon Schubert HANDLE_TOKEN2 ("|=", ASSIGN_MODIFY);
17735796c8dcSSimon Schubert HANDLE_TOKEN2 ("||", OROR);
17745796c8dcSSimon Schubert lexptr++;
17755796c8dcSSimon Schubert return c;
17765796c8dcSSimon Schubert case '&':
17775796c8dcSSimon Schubert HANDLE_TOKEN2 ("&=", ASSIGN_MODIFY);
17785796c8dcSSimon Schubert HANDLE_TOKEN2 ("&&", ANDAND);
17795796c8dcSSimon Schubert lexptr++;
17805796c8dcSSimon Schubert return c;
17815796c8dcSSimon Schubert case '^':
17825796c8dcSSimon Schubert HANDLE_TOKEN2 ("^=", ASSIGN_MODIFY);
17835796c8dcSSimon Schubert lexptr++;
17845796c8dcSSimon Schubert return c;
17855796c8dcSSimon Schubert case '!':
17865796c8dcSSimon Schubert HANDLE_TOKEN2 ("!=", NOTEQUAL);
17875796c8dcSSimon Schubert lexptr++;
17885796c8dcSSimon Schubert return c;
17895796c8dcSSimon Schubert case '<':
17905796c8dcSSimon Schubert HANDLE_TOKEN3 ("<<=", ASSIGN_MODIFY);
17915796c8dcSSimon Schubert HANDLE_TOKEN2 ("<=", LEQ);
17925796c8dcSSimon Schubert HANDLE_TOKEN2 ("<<", LSH);
17935796c8dcSSimon Schubert lexptr++;
17945796c8dcSSimon Schubert return c;
17955796c8dcSSimon Schubert case '>':
17965796c8dcSSimon Schubert HANDLE_TOKEN3 (">>=", ASSIGN_MODIFY);
17975796c8dcSSimon Schubert HANDLE_TOKEN2 (">=", GEQ);
17985796c8dcSSimon Schubert HANDLE_TOKEN2 (">>", RSH);
17995796c8dcSSimon Schubert lexptr++;
18005796c8dcSSimon Schubert return c;
18015796c8dcSSimon Schubert case '=':
18025796c8dcSSimon Schubert HANDLE_TOKEN2 ("==", EQUAL);
18035796c8dcSSimon Schubert lexptr++;
18045796c8dcSSimon Schubert return c;
18055796c8dcSSimon Schubert case ':':
18065796c8dcSSimon Schubert HANDLE_TOKEN2 ("::", COLONCOLON);
18075796c8dcSSimon Schubert lexptr++;
18085796c8dcSSimon Schubert return c;
18095796c8dcSSimon Schubert
18105796c8dcSSimon Schubert case '[':
18115796c8dcSSimon Schubert case ']':
18125796c8dcSSimon Schubert case '?':
18135796c8dcSSimon Schubert case '@':
18145796c8dcSSimon Schubert case '~':
18155796c8dcSSimon Schubert case '{':
18165796c8dcSSimon Schubert case '}':
18175796c8dcSSimon Schubert symbol:
18185796c8dcSSimon Schubert lexptr++;
18195796c8dcSSimon Schubert return c;
18205796c8dcSSimon Schubert
18215796c8dcSSimon Schubert case '"':
18225796c8dcSSimon Schubert /* These can't occur in C++ names. */
1823c50c785cSJohn Marino yyerror (_("unexpected string literal"));
18245796c8dcSSimon Schubert return ERROR;
18255796c8dcSSimon Schubert }
18265796c8dcSSimon Schubert
18275796c8dcSSimon Schubert if (!(c == '_' || c == '$' || ISALPHA (c)))
18285796c8dcSSimon Schubert {
18295796c8dcSSimon Schubert /* We must have come across a bad character (e.g. ';'). */
1830c50c785cSJohn Marino yyerror (_("invalid character"));
18315796c8dcSSimon Schubert return ERROR;
18325796c8dcSSimon Schubert }
18335796c8dcSSimon Schubert
18345796c8dcSSimon Schubert /* It's a name. See how long it is. */
18355796c8dcSSimon Schubert namelen = 0;
18365796c8dcSSimon Schubert do
18375796c8dcSSimon Schubert c = tokstart[++namelen];
18385796c8dcSSimon Schubert while (ISALNUM (c) || c == '_' || c == '$');
18395796c8dcSSimon Schubert
18405796c8dcSSimon Schubert lexptr += namelen;
18415796c8dcSSimon Schubert
18425796c8dcSSimon Schubert /* Catch specific keywords. Notice that some of the keywords contain
18435796c8dcSSimon Schubert spaces, and are sorted by the length of the first word. They must
18445796c8dcSSimon Schubert all include a trailing space in the string comparison. */
18455796c8dcSSimon Schubert switch (namelen)
18465796c8dcSSimon Schubert {
18475796c8dcSSimon Schubert case 16:
18485796c8dcSSimon Schubert if (strncmp (tokstart, "reinterpret_cast", 16) == 0)
18495796c8dcSSimon Schubert return REINTERPRET_CAST;
18505796c8dcSSimon Schubert break;
18515796c8dcSSimon Schubert case 12:
18525796c8dcSSimon Schubert if (strncmp (tokstart, "construction vtable for ", 24) == 0)
18535796c8dcSSimon Schubert {
18545796c8dcSSimon Schubert lexptr = tokstart + 24;
18555796c8dcSSimon Schubert return CONSTRUCTION_VTABLE;
18565796c8dcSSimon Schubert }
18575796c8dcSSimon Schubert if (strncmp (tokstart, "dynamic_cast", 12) == 0)
18585796c8dcSSimon Schubert return DYNAMIC_CAST;
18595796c8dcSSimon Schubert break;
18605796c8dcSSimon Schubert case 11:
18615796c8dcSSimon Schubert if (strncmp (tokstart, "static_cast", 11) == 0)
18625796c8dcSSimon Schubert return STATIC_CAST;
18635796c8dcSSimon Schubert break;
18645796c8dcSSimon Schubert case 9:
18655796c8dcSSimon Schubert HANDLE_SPECIAL ("covariant return thunk to ", DEMANGLE_COMPONENT_COVARIANT_THUNK);
18665796c8dcSSimon Schubert HANDLE_SPECIAL ("reference temporary for ", DEMANGLE_COMPONENT_REFTEMP);
18675796c8dcSSimon Schubert break;
18685796c8dcSSimon Schubert case 8:
18695796c8dcSSimon Schubert HANDLE_SPECIAL ("typeinfo for ", DEMANGLE_COMPONENT_TYPEINFO);
18705796c8dcSSimon Schubert HANDLE_SPECIAL ("typeinfo fn for ", DEMANGLE_COMPONENT_TYPEINFO_FN);
18715796c8dcSSimon Schubert HANDLE_SPECIAL ("typeinfo name for ", DEMANGLE_COMPONENT_TYPEINFO_NAME);
18725796c8dcSSimon Schubert if (strncmp (tokstart, "operator", 8) == 0)
18735796c8dcSSimon Schubert return OPERATOR;
18745796c8dcSSimon Schubert if (strncmp (tokstart, "restrict", 8) == 0)
18755796c8dcSSimon Schubert return RESTRICT;
18765796c8dcSSimon Schubert if (strncmp (tokstart, "unsigned", 8) == 0)
18775796c8dcSSimon Schubert return UNSIGNED;
18785796c8dcSSimon Schubert if (strncmp (tokstart, "template", 8) == 0)
18795796c8dcSSimon Schubert return TEMPLATE;
18805796c8dcSSimon Schubert if (strncmp (tokstart, "volatile", 8) == 0)
18815796c8dcSSimon Schubert return VOLATILE_KEYWORD;
18825796c8dcSSimon Schubert break;
18835796c8dcSSimon Schubert case 7:
18845796c8dcSSimon Schubert HANDLE_SPECIAL ("virtual thunk to ", DEMANGLE_COMPONENT_VIRTUAL_THUNK);
18855796c8dcSSimon Schubert if (strncmp (tokstart, "wchar_t", 7) == 0)
18865796c8dcSSimon Schubert return WCHAR_T;
18875796c8dcSSimon Schubert break;
18885796c8dcSSimon Schubert case 6:
18895796c8dcSSimon Schubert if (strncmp (tokstart, "global constructors keyed to ", 29) == 0)
18905796c8dcSSimon Schubert {
18915796c8dcSSimon Schubert const char *p;
18925796c8dcSSimon Schubert lexptr = tokstart + 29;
18935796c8dcSSimon Schubert yylval.lval = DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS;
18945796c8dcSSimon Schubert /* Find the end of the symbol. */
18955796c8dcSSimon Schubert p = symbol_end (lexptr);
18965796c8dcSSimon Schubert yylval.comp = make_name (lexptr, p - lexptr);
18975796c8dcSSimon Schubert lexptr = p;
18985796c8dcSSimon Schubert return DEMANGLER_SPECIAL;
18995796c8dcSSimon Schubert }
19005796c8dcSSimon Schubert if (strncmp (tokstart, "global destructors keyed to ", 28) == 0)
19015796c8dcSSimon Schubert {
19025796c8dcSSimon Schubert const char *p;
19035796c8dcSSimon Schubert lexptr = tokstart + 28;
19045796c8dcSSimon Schubert yylval.lval = DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS;
19055796c8dcSSimon Schubert /* Find the end of the symbol. */
19065796c8dcSSimon Schubert p = symbol_end (lexptr);
19075796c8dcSSimon Schubert yylval.comp = make_name (lexptr, p - lexptr);
19085796c8dcSSimon Schubert lexptr = p;
19095796c8dcSSimon Schubert return DEMANGLER_SPECIAL;
19105796c8dcSSimon Schubert }
19115796c8dcSSimon Schubert
19125796c8dcSSimon Schubert HANDLE_SPECIAL ("vtable for ", DEMANGLE_COMPONENT_VTABLE);
19135796c8dcSSimon Schubert if (strncmp (tokstart, "delete", 6) == 0)
19145796c8dcSSimon Schubert return DELETE;
19155796c8dcSSimon Schubert if (strncmp (tokstart, "struct", 6) == 0)
19165796c8dcSSimon Schubert return STRUCT;
19175796c8dcSSimon Schubert if (strncmp (tokstart, "signed", 6) == 0)
19185796c8dcSSimon Schubert return SIGNED_KEYWORD;
19195796c8dcSSimon Schubert if (strncmp (tokstart, "sizeof", 6) == 0)
19205796c8dcSSimon Schubert return SIZEOF;
19215796c8dcSSimon Schubert if (strncmp (tokstart, "double", 6) == 0)
19225796c8dcSSimon Schubert return DOUBLE_KEYWORD;
19235796c8dcSSimon Schubert break;
19245796c8dcSSimon Schubert case 5:
19255796c8dcSSimon Schubert HANDLE_SPECIAL ("guard variable for ", DEMANGLE_COMPONENT_GUARD);
19265796c8dcSSimon Schubert if (strncmp (tokstart, "false", 5) == 0)
19275796c8dcSSimon Schubert return FALSEKEYWORD;
19285796c8dcSSimon Schubert if (strncmp (tokstart, "class", 5) == 0)
19295796c8dcSSimon Schubert return CLASS;
19305796c8dcSSimon Schubert if (strncmp (tokstart, "union", 5) == 0)
19315796c8dcSSimon Schubert return UNION;
19325796c8dcSSimon Schubert if (strncmp (tokstart, "float", 5) == 0)
19335796c8dcSSimon Schubert return FLOAT_KEYWORD;
19345796c8dcSSimon Schubert if (strncmp (tokstart, "short", 5) == 0)
19355796c8dcSSimon Schubert return SHORT;
19365796c8dcSSimon Schubert if (strncmp (tokstart, "const", 5) == 0)
19375796c8dcSSimon Schubert return CONST_KEYWORD;
19385796c8dcSSimon Schubert break;
19395796c8dcSSimon Schubert case 4:
19405796c8dcSSimon Schubert if (strncmp (tokstart, "void", 4) == 0)
19415796c8dcSSimon Schubert return VOID;
19425796c8dcSSimon Schubert if (strncmp (tokstart, "bool", 4) == 0)
19435796c8dcSSimon Schubert return BOOL;
19445796c8dcSSimon Schubert if (strncmp (tokstart, "char", 4) == 0)
19455796c8dcSSimon Schubert return CHAR;
19465796c8dcSSimon Schubert if (strncmp (tokstart, "enum", 4) == 0)
19475796c8dcSSimon Schubert return ENUM;
19485796c8dcSSimon Schubert if (strncmp (tokstart, "long", 4) == 0)
19495796c8dcSSimon Schubert return LONG;
19505796c8dcSSimon Schubert if (strncmp (tokstart, "true", 4) == 0)
19515796c8dcSSimon Schubert return TRUEKEYWORD;
19525796c8dcSSimon Schubert break;
19535796c8dcSSimon Schubert case 3:
19545796c8dcSSimon Schubert HANDLE_SPECIAL ("VTT for ", DEMANGLE_COMPONENT_VTT);
19555796c8dcSSimon Schubert HANDLE_SPECIAL ("non-virtual thunk to ", DEMANGLE_COMPONENT_THUNK);
19565796c8dcSSimon Schubert if (strncmp (tokstart, "new", 3) == 0)
19575796c8dcSSimon Schubert return NEW;
19585796c8dcSSimon Schubert if (strncmp (tokstart, "int", 3) == 0)
19595796c8dcSSimon Schubert return INT_KEYWORD;
19605796c8dcSSimon Schubert break;
19615796c8dcSSimon Schubert default:
19625796c8dcSSimon Schubert break;
19635796c8dcSSimon Schubert }
19645796c8dcSSimon Schubert
19655796c8dcSSimon Schubert yylval.comp = make_name (tokstart, namelen);
19665796c8dcSSimon Schubert return NAME;
19675796c8dcSSimon Schubert }
19685796c8dcSSimon Schubert
19695796c8dcSSimon Schubert static void
yyerror(char * msg)19705796c8dcSSimon Schubert yyerror (char *msg)
19715796c8dcSSimon Schubert {
19725796c8dcSSimon Schubert if (global_errmsg)
19735796c8dcSSimon Schubert return;
19745796c8dcSSimon Schubert
19755796c8dcSSimon Schubert error_lexptr = prev_lexptr;
19765796c8dcSSimon Schubert global_errmsg = msg ? msg : "parse error";
19775796c8dcSSimon Schubert }
19785796c8dcSSimon Schubert
19795796c8dcSSimon Schubert /* Allocate a chunk of the components we'll need to build a tree. We
19805796c8dcSSimon Schubert generally allocate too many components, but the extra memory usage
19815796c8dcSSimon Schubert doesn't hurt because the trees are temporary and the storage is
19825796c8dcSSimon Schubert reused. More may be allocated later, by d_grab. */
1983a45ae5f8SJohn Marino static struct demangle_info *
allocate_info(void)19845796c8dcSSimon Schubert allocate_info (void)
19855796c8dcSSimon Schubert {
1986a45ae5f8SJohn Marino struct demangle_info *info = malloc (sizeof (struct demangle_info));
19875796c8dcSSimon Schubert
1988a45ae5f8SJohn Marino info->next = NULL;
1989a45ae5f8SJohn Marino info->used = 0;
1990a45ae5f8SJohn Marino return info;
19915796c8dcSSimon Schubert }
19925796c8dcSSimon Schubert
19935796c8dcSSimon Schubert /* Convert RESULT to a string. The return value is allocated
19945796c8dcSSimon Schubert using xmalloc. ESTIMATED_LEN is used only as a guide to the
19955796c8dcSSimon Schubert length of the result. This functions handles a few cases that
19965796c8dcSSimon Schubert cplus_demangle_print does not, specifically the global destructor
19975796c8dcSSimon Schubert and constructor labels. */
19985796c8dcSSimon Schubert
19995796c8dcSSimon Schubert char *
cp_comp_to_string(struct demangle_component * result,int estimated_len)20005796c8dcSSimon Schubert cp_comp_to_string (struct demangle_component *result, int estimated_len)
20015796c8dcSSimon Schubert {
20025796c8dcSSimon Schubert size_t err;
20035796c8dcSSimon Schubert
20045796c8dcSSimon Schubert return cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, estimated_len,
20055796c8dcSSimon Schubert &err);
20065796c8dcSSimon Schubert }
20075796c8dcSSimon Schubert
2008a45ae5f8SJohn Marino /* A convenience function to allocate and initialize a new struct
2009a45ae5f8SJohn Marino demangled_parse_info. */
2010a45ae5f8SJohn Marino
2011a45ae5f8SJohn Marino struct demangle_parse_info *
cp_new_demangle_parse_info(void)2012a45ae5f8SJohn Marino cp_new_demangle_parse_info (void)
2013a45ae5f8SJohn Marino {
2014a45ae5f8SJohn Marino struct demangle_parse_info *info;
2015a45ae5f8SJohn Marino
2016a45ae5f8SJohn Marino info = malloc (sizeof (struct demangle_parse_info));
2017a45ae5f8SJohn Marino info->info = NULL;
2018a45ae5f8SJohn Marino info->tree = NULL;
2019a45ae5f8SJohn Marino obstack_init (&info->obstack);
2020a45ae5f8SJohn Marino
2021a45ae5f8SJohn Marino return info;
2022a45ae5f8SJohn Marino }
2023a45ae5f8SJohn Marino
2024a45ae5f8SJohn Marino /* Free any memory associated with the given PARSE_INFO. */
2025a45ae5f8SJohn Marino
2026a45ae5f8SJohn Marino void
cp_demangled_name_parse_free(struct demangle_parse_info * parse_info)2027a45ae5f8SJohn Marino cp_demangled_name_parse_free (struct demangle_parse_info *parse_info)
2028a45ae5f8SJohn Marino {
2029a45ae5f8SJohn Marino struct demangle_info *info = parse_info->info;
2030a45ae5f8SJohn Marino
2031a45ae5f8SJohn Marino /* Free any allocated chunks of memory for the parse. */
2032a45ae5f8SJohn Marino while (info != NULL)
2033a45ae5f8SJohn Marino {
2034a45ae5f8SJohn Marino struct demangle_info *next = info->next;
2035a45ae5f8SJohn Marino
2036a45ae5f8SJohn Marino free (info);
2037a45ae5f8SJohn Marino info = next;
2038a45ae5f8SJohn Marino }
2039a45ae5f8SJohn Marino
2040a45ae5f8SJohn Marino /* Free any memory allocated during typedef replacement. */
2041a45ae5f8SJohn Marino obstack_free (&parse_info->obstack, NULL);
2042a45ae5f8SJohn Marino
2043a45ae5f8SJohn Marino /* Free the parser info. */
2044a45ae5f8SJohn Marino free (parse_info);
2045a45ae5f8SJohn Marino }
2046a45ae5f8SJohn Marino
2047a45ae5f8SJohn Marino /* Merge the two parse trees given by DEST and SRC. The parse tree
2048a45ae5f8SJohn Marino in SRC is attached to DEST at the node represented by TARGET.
2049a45ae5f8SJohn Marino SRC is then freed.
2050a45ae5f8SJohn Marino
2051a45ae5f8SJohn Marino NOTE 1: Since there is no API to merge obstacks, this function does
2052a45ae5f8SJohn Marino even attempt to try it. Fortunately, we do not (yet?) need this ability.
2053a45ae5f8SJohn Marino The code will assert if SRC->obstack is not empty.
2054a45ae5f8SJohn Marino
2055a45ae5f8SJohn Marino NOTE 2: The string from which SRC was parsed must not be freed, since
2056a45ae5f8SJohn Marino this function will place pointers to that string into DEST. */
2057a45ae5f8SJohn Marino
2058a45ae5f8SJohn Marino void
cp_merge_demangle_parse_infos(struct demangle_parse_info * dest,struct demangle_component * target,struct demangle_parse_info * src)2059a45ae5f8SJohn Marino cp_merge_demangle_parse_infos (struct demangle_parse_info *dest,
2060a45ae5f8SJohn Marino struct demangle_component *target,
2061a45ae5f8SJohn Marino struct demangle_parse_info *src)
2062a45ae5f8SJohn Marino
2063a45ae5f8SJohn Marino {
2064a45ae5f8SJohn Marino struct demangle_info *di;
2065a45ae5f8SJohn Marino
2066a45ae5f8SJohn Marino /* Copy the SRC's parse data into DEST. */
2067a45ae5f8SJohn Marino *target = *src->tree;
2068a45ae5f8SJohn Marino di = dest->info;
2069a45ae5f8SJohn Marino while (di->next != NULL)
2070a45ae5f8SJohn Marino di = di->next;
2071a45ae5f8SJohn Marino di->next = src->info;
2072a45ae5f8SJohn Marino
2073a45ae5f8SJohn Marino /* Clear the (pointer to) SRC's parse data so that it is not freed when
2074a45ae5f8SJohn Marino cp_demangled_parse_info_free is called. */
2075a45ae5f8SJohn Marino src->info = NULL;
2076a45ae5f8SJohn Marino
2077a45ae5f8SJohn Marino /* Free SRC. */
2078a45ae5f8SJohn Marino cp_demangled_name_parse_free (src);
2079a45ae5f8SJohn Marino }
2080a45ae5f8SJohn Marino
20815796c8dcSSimon Schubert /* Convert a demangled name to a demangle_component tree. On success,
2082a45ae5f8SJohn Marino a structure containing the root of the new tree is returned; it must
2083a45ae5f8SJohn Marino be freed by calling cp_demangled_name_parse_free. On error, NULL is
20845796c8dcSSimon Schubert returned, and an error message will be set in *ERRMSG (which does
20855796c8dcSSimon Schubert not need to be freed). */
20865796c8dcSSimon Schubert
2087a45ae5f8SJohn Marino struct demangle_parse_info *
cp_demangled_name_to_comp(const char * demangled_name,const char ** errmsg)20885796c8dcSSimon Schubert cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg)
20895796c8dcSSimon Schubert {
20905796c8dcSSimon Schubert static char errbuf[60];
2091a45ae5f8SJohn Marino struct demangle_parse_info *result;
20925796c8dcSSimon Schubert
20935796c8dcSSimon Schubert prev_lexptr = lexptr = demangled_name;
20945796c8dcSSimon Schubert error_lexptr = NULL;
20955796c8dcSSimon Schubert global_errmsg = NULL;
20965796c8dcSSimon Schubert
2097a45ae5f8SJohn Marino demangle_info = allocate_info ();
2098a45ae5f8SJohn Marino
2099a45ae5f8SJohn Marino result = cp_new_demangle_parse_info ();
2100a45ae5f8SJohn Marino result->info = demangle_info;
21015796c8dcSSimon Schubert
21025796c8dcSSimon Schubert if (yyparse ())
21035796c8dcSSimon Schubert {
21045796c8dcSSimon Schubert if (global_errmsg && errmsg)
21055796c8dcSSimon Schubert {
21065796c8dcSSimon Schubert snprintf (errbuf, sizeof (errbuf) - 2, "%s, near `%s",
21075796c8dcSSimon Schubert global_errmsg, error_lexptr);
21085796c8dcSSimon Schubert strcat (errbuf, "'");
21095796c8dcSSimon Schubert *errmsg = errbuf;
21105796c8dcSSimon Schubert }
2111a45ae5f8SJohn Marino cp_demangled_name_parse_free (result);
21125796c8dcSSimon Schubert return NULL;
21135796c8dcSSimon Schubert }
21145796c8dcSSimon Schubert
2115a45ae5f8SJohn Marino result->tree = global_result;
21165796c8dcSSimon Schubert global_result = NULL;
21175796c8dcSSimon Schubert
21185796c8dcSSimon Schubert return result;
21195796c8dcSSimon Schubert }
21205796c8dcSSimon Schubert
21215796c8dcSSimon Schubert #ifdef TEST_CPNAMES
21225796c8dcSSimon Schubert
21235796c8dcSSimon Schubert static void
cp_print(struct demangle_component * result)21245796c8dcSSimon Schubert cp_print (struct demangle_component *result)
21255796c8dcSSimon Schubert {
21265796c8dcSSimon Schubert char *str;
21275796c8dcSSimon Schubert size_t err = 0;
21285796c8dcSSimon Schubert
21295796c8dcSSimon Schubert str = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, 64, &err);
21305796c8dcSSimon Schubert if (str == NULL)
21315796c8dcSSimon Schubert return;
21325796c8dcSSimon Schubert
21335796c8dcSSimon Schubert fputs (str, stdout);
21345796c8dcSSimon Schubert
21355796c8dcSSimon Schubert free (str);
21365796c8dcSSimon Schubert }
21375796c8dcSSimon Schubert
21385796c8dcSSimon Schubert static char
trim_chars(char * lexptr,char ** extra_chars)21395796c8dcSSimon Schubert trim_chars (char *lexptr, char **extra_chars)
21405796c8dcSSimon Schubert {
21415796c8dcSSimon Schubert char *p = (char *) symbol_end (lexptr);
21425796c8dcSSimon Schubert char c = 0;
21435796c8dcSSimon Schubert
21445796c8dcSSimon Schubert if (*p)
21455796c8dcSSimon Schubert {
21465796c8dcSSimon Schubert c = *p;
21475796c8dcSSimon Schubert *p = 0;
21485796c8dcSSimon Schubert *extra_chars = p + 1;
21495796c8dcSSimon Schubert }
21505796c8dcSSimon Schubert
21515796c8dcSSimon Schubert return c;
21525796c8dcSSimon Schubert }
21535796c8dcSSimon Schubert
21545796c8dcSSimon Schubert /* When this file is built as a standalone program, xmalloc comes from
21555796c8dcSSimon Schubert libiberty --- in which case we have to provide xfree ourselves. */
21565796c8dcSSimon Schubert
21575796c8dcSSimon Schubert void
xfree(void * ptr)21585796c8dcSSimon Schubert xfree (void *ptr)
21595796c8dcSSimon Schubert {
21605796c8dcSSimon Schubert if (ptr != NULL)
2161a45ae5f8SJohn Marino {
2162a45ae5f8SJohn Marino /* Literal `free' would get translated back to xfree again. */
2163a45ae5f8SJohn Marino CONCAT2 (fr,ee) (ptr);
2164a45ae5f8SJohn Marino }
2165a45ae5f8SJohn Marino }
2166a45ae5f8SJohn Marino
2167a45ae5f8SJohn Marino /* GDB normally defines internal_error itself, but when this file is built
2168a45ae5f8SJohn Marino as a standalone program, we must also provide an implementation. */
2169a45ae5f8SJohn Marino
2170a45ae5f8SJohn Marino void
internal_error(const char * file,int line,const char * fmt,...)2171a45ae5f8SJohn Marino internal_error (const char *file, int line, const char *fmt, ...)
2172a45ae5f8SJohn Marino {
2173a45ae5f8SJohn Marino va_list ap;
2174a45ae5f8SJohn Marino
2175a45ae5f8SJohn Marino va_start (ap, fmt);
2176a45ae5f8SJohn Marino fprintf (stderr, "%s:%d: internal error: ", file, line);
2177a45ae5f8SJohn Marino vfprintf (stderr, fmt, ap);
2178a45ae5f8SJohn Marino exit (1);
21795796c8dcSSimon Schubert }
21805796c8dcSSimon Schubert
21815796c8dcSSimon Schubert int
main(int argc,char ** argv)21825796c8dcSSimon Schubert main (int argc, char **argv)
21835796c8dcSSimon Schubert {
21845796c8dcSSimon Schubert char *str2, *extra_chars = "", c;
21855796c8dcSSimon Schubert char buf[65536];
21865796c8dcSSimon Schubert int arg;
21875796c8dcSSimon Schubert const char *errmsg;
2188a45ae5f8SJohn Marino struct demangle_parse_info *result;
21895796c8dcSSimon Schubert
21905796c8dcSSimon Schubert arg = 1;
21915796c8dcSSimon Schubert if (argv[arg] && strcmp (argv[arg], "--debug") == 0)
21925796c8dcSSimon Schubert {
21935796c8dcSSimon Schubert yydebug = 1;
21945796c8dcSSimon Schubert arg++;
21955796c8dcSSimon Schubert }
21965796c8dcSSimon Schubert
21975796c8dcSSimon Schubert if (argv[arg] == NULL)
21985796c8dcSSimon Schubert while (fgets (buf, 65536, stdin) != NULL)
21995796c8dcSSimon Schubert {
22005796c8dcSSimon Schubert int len;
22015796c8dcSSimon Schubert buf[strlen (buf) - 1] = 0;
22025796c8dcSSimon Schubert /* Use DMGL_VERBOSE to get expanded standard substitutions. */
22035796c8dcSSimon Schubert c = trim_chars (buf, &extra_chars);
22045796c8dcSSimon Schubert str2 = cplus_demangle (buf, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
22055796c8dcSSimon Schubert if (str2 == NULL)
22065796c8dcSSimon Schubert {
2207a45ae5f8SJohn Marino printf ("Demangling error\n");
22085796c8dcSSimon Schubert if (c)
22095796c8dcSSimon Schubert printf ("%s%c%s\n", buf, c, extra_chars);
22105796c8dcSSimon Schubert else
22115796c8dcSSimon Schubert printf ("%s\n", buf);
22125796c8dcSSimon Schubert continue;
22135796c8dcSSimon Schubert }
22145796c8dcSSimon Schubert result = cp_demangled_name_to_comp (str2, &errmsg);
22155796c8dcSSimon Schubert if (result == NULL)
22165796c8dcSSimon Schubert {
22175796c8dcSSimon Schubert fputs (errmsg, stderr);
22185796c8dcSSimon Schubert fputc ('\n', stderr);
22195796c8dcSSimon Schubert continue;
22205796c8dcSSimon Schubert }
22215796c8dcSSimon Schubert
2222a45ae5f8SJohn Marino cp_print (result->tree);
2223a45ae5f8SJohn Marino cp_demangled_name_parse_free (result);
22245796c8dcSSimon Schubert
22255796c8dcSSimon Schubert free (str2);
22265796c8dcSSimon Schubert if (c)
22275796c8dcSSimon Schubert {
22285796c8dcSSimon Schubert putchar (c);
22295796c8dcSSimon Schubert fputs (extra_chars, stdout);
22305796c8dcSSimon Schubert }
22315796c8dcSSimon Schubert putchar ('\n');
22325796c8dcSSimon Schubert }
22335796c8dcSSimon Schubert else
22345796c8dcSSimon Schubert {
22355796c8dcSSimon Schubert result = cp_demangled_name_to_comp (argv[arg], &errmsg);
22365796c8dcSSimon Schubert if (result == NULL)
22375796c8dcSSimon Schubert {
22385796c8dcSSimon Schubert fputs (errmsg, stderr);
22395796c8dcSSimon Schubert fputc ('\n', stderr);
22405796c8dcSSimon Schubert return 0;
22415796c8dcSSimon Schubert }
2242a45ae5f8SJohn Marino cp_print (result->tree);
2243a45ae5f8SJohn Marino cp_demangled_name_parse_free (result);
22445796c8dcSSimon Schubert putchar ('\n');
22455796c8dcSSimon Schubert }
22465796c8dcSSimon Schubert return 0;
22475796c8dcSSimon Schubert }
22485796c8dcSSimon Schubert
22495796c8dcSSimon Schubert #endif
2250