too messy, particularly when such includes can be inserted at random
times by the parser generator. */
+/* The Bison manual says that %pure-parser is deprecated, but we use
+ it anyway because it also works with Byacc. That is also why
+ this uses %lex-param and %parse-param rather than the simpler
+ %param -- Byacc does not support the latter. */
+%pure-parser
+%lex-param {struct cpname_state *state}
+%parse-param {struct cpname_state *state}
+
%{
#include "defs.h"
#define GDB_YY_REMAP_PREFIX cpname
#include "yy-remap.h"
-/* Bison does not make it easy to create a parser without global
- state, unfortunately. Here are all the global variables used
- in this parser. */
-
-/* LEXPTR is the current pointer into our lex buffer. PREV_LEXPTR
- is the start of the last token lexed, only used for diagnostics.
- ERROR_LEXPTR is the first place an error occurred. GLOBAL_ERRMSG
- is the first error message encountered. */
-
-static const char *lexptr, *prev_lexptr, *error_lexptr, *global_errmsg;
-
/* The components built by the parser are allocated ahead of time,
and cached in this structure. */
struct demangle_component comps[ALLOC_CHUNK];
};
-static struct demangle_info *demangle_info;
+struct cpname_state
+{
+/* LEXPTR is the current pointer into our lex buffer. PREV_LEXPTR
+ is the start of the last token lexed, only used for diagnostics.
+ ERROR_LEXPTR is the first place an error occurred. GLOBAL_ERRMSG
+ is the first error message encountered. */
+
+ const char *lexptr, *prev_lexptr, *error_lexptr, *global_errmsg;
+
+ struct demangle_info *demangle_info;
+
+ /* The parse tree created by the parser is stored here after a
+ successful parse. */
+
+ struct demangle_component *global_result;
+};
static struct demangle_component *
-d_grab (void)
+d_grab (cpname_state *state)
{
struct demangle_info *more;
- if (demangle_info->used >= ALLOC_CHUNK)
+ if (state->demangle_info->used >= ALLOC_CHUNK)
{
- if (demangle_info->next == NULL)
+ if (state->demangle_info->next == NULL)
{
more = XNEW (struct demangle_info);
more->next = NULL;
- demangle_info->next = more;
+ state->demangle_info->next = more;
}
else
- more = demangle_info->next;
+ more = state->demangle_info->next;
more->used = 0;
- demangle_info = more;
+ state->demangle_info = more;
}
- return &demangle_info->comps[demangle_info->used++];
+ return &state->demangle_info->comps[state->demangle_info->used++];
}
-/* The parse tree created by the parser is stored here after a successful
- parse. */
-
-static struct demangle_component *global_result;
-
/* Prototypes for helper functions used when constructing the parse
tree. */
-static struct demangle_component *d_qualify (struct demangle_component *, int,
+static struct demangle_component *d_qualify (cpname_state *state,
+ struct demangle_component *, int,
int);
-static struct demangle_component *d_int_type (int);
+static struct demangle_component *d_int_type (cpname_state *state, int);
-static struct demangle_component *d_unary (const char *,
+static struct demangle_component *d_unary (cpname_state *state, const char *,
struct demangle_component *);
-static struct demangle_component *d_binary (const char *,
+static struct demangle_component *d_binary (cpname_state *state, const char *,
struct demangle_component *,
struct demangle_component *);
#define INT_SIGNED (1 << 4)
#define INT_UNSIGNED (1 << 5)
-int yyparse (void);
-static int yylex (void);
-static void yyerror (const char *);
-
/* Enable yydebug for the stand-alone parser. */
#ifdef TEST_CPNAMES
# define YYDEBUG 1
allocation from our global store, and return the allocated component. */
static struct demangle_component *
-fill_comp (enum demangle_component_type d_type, struct demangle_component *lhs,
+fill_comp (cpname_state *state,
+ enum demangle_component_type d_type, struct demangle_component *lhs,
struct demangle_component *rhs)
{
- struct demangle_component *ret = d_grab ();
+ struct demangle_component *ret = d_grab (state);
int i;
i = cplus_demangle_fill_component (ret, d_type, lhs, rhs);
}
static struct demangle_component *
-make_operator (const char *name, int args)
+make_operator (cpname_state *state, const char *name, int args)
{
- struct demangle_component *ret = d_grab ();
+ struct demangle_component *ret = d_grab (state);
int i;
i = cplus_demangle_fill_operator (ret, name, args);
}
static struct demangle_component *
-make_dtor (enum gnu_v3_dtor_kinds kind, struct demangle_component *name)
+make_dtor (cpname_state *state, enum gnu_v3_dtor_kinds kind,
+ struct demangle_component *name)
{
- struct demangle_component *ret = d_grab ();
+ struct demangle_component *ret = d_grab (state);
int i;
i = cplus_demangle_fill_dtor (ret, kind, name);
}
static struct demangle_component *
-make_builtin_type (const char *name)
+make_builtin_type (cpname_state *state, const char *name)
{
- struct demangle_component *ret = d_grab ();
+ struct demangle_component *ret = d_grab (state);
int i;
i = cplus_demangle_fill_builtin_type (ret, name);
}
static struct demangle_component *
-make_name (const char *name, int len)
+make_name (cpname_state *state, const char *name, int len)
{
- struct demangle_component *ret = d_grab ();
+ struct demangle_component *ret = d_grab (state);
int i;
i = cplus_demangle_fill_name (ret, name, len);
const char *opname;
}
+%{
+static int yylex (YYSTYPE *, cpname_state *);
+static void yyerror (cpname_state *, const char *);
+%}
+
%type <comp> exp exp1 type start start_opt oper colon_name
%type <comp> unqualified_name colon_ext_name
%type <comp> templ template_arg
%%
result : start
- { global_result = $1; }
+ { state->global_result = $1; }
;
start : type
start_opt is used to handle "function-local" variables and
types. */
| typespec_2 function_arglist start_opt
- { $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
- if ($3) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_TYPED_NAME,
+ $1, $2.comp);
+ if ($3)
+ $$ = fill_comp (state,
+ DEMANGLE_COMPONENT_LOCAL_NAME,
+ $$, $3);
+ }
| colon_ext_only function_arglist start_opt
- { $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
- if ($3) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
+ if ($3) $$ = fill_comp (state, DEMANGLE_COMPONENT_LOCAL_NAME, $$, $3); }
| conversion_op_name start_opt
{ $$ = $1.comp;
- if ($2) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2); }
+ if ($2) $$ = fill_comp (state, DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2); }
| conversion_op_name abstract_declarator_fn
{ if ($2.last)
{
}
/* If we have an arglist, build a function type. */
if ($2.fn.comp)
- $$ = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1.comp, $2.fn.comp);
+ $$ = fill_comp (state, DEMANGLE_COMPONENT_TYPED_NAME, $1.comp, $2.fn.comp);
else
$$ = $1.comp;
- if ($2.start) $$ = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2.start);
+ if ($2.start) $$ = fill_comp (state, DEMANGLE_COMPONENT_LOCAL_NAME, $$, $2.start);
}
;
demangler_special
: DEMANGLER_SPECIAL start
- { $$ = fill_comp ((enum demangle_component_type) $1, $2, NULL); }
+ { $$ = fill_comp (state, (enum demangle_component_type) $1, $2, NULL); }
| CONSTRUCTION_VTABLE start CONSTRUCTION_IN start
- { $$ = fill_comp (DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, $2, $4); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, $2, $4); }
;
oper : OPERATOR NEW
{
/* Match the whitespacing of cplus_demangle_operators.
It would abort on unrecognized string otherwise. */
- $$ = make_operator ("new", 3);
+ $$ = make_operator (state, "new", 3);
}
| OPERATOR DELETE
{
/* Match the whitespacing of cplus_demangle_operators.
It would abort on unrecognized string otherwise. */
- $$ = make_operator ("delete ", 1);
+ $$ = make_operator (state, "delete ", 1);
}
| OPERATOR NEW '[' ']'
{
/* Match the whitespacing of cplus_demangle_operators.
It would abort on unrecognized string otherwise. */
- $$ = make_operator ("new[]", 3);
+ $$ = make_operator (state, "new[]", 3);
}
| OPERATOR DELETE '[' ']'
{
/* Match the whitespacing of cplus_demangle_operators.
It would abort on unrecognized string otherwise. */
- $$ = make_operator ("delete[] ", 1);
+ $$ = make_operator (state, "delete[] ", 1);
}
| OPERATOR '+'
- { $$ = make_operator ("+", 2); }
+ { $$ = make_operator (state, "+", 2); }
| OPERATOR '-'
- { $$ = make_operator ("-", 2); }
+ { $$ = make_operator (state, "-", 2); }
| OPERATOR '*'
- { $$ = make_operator ("*", 2); }
+ { $$ = make_operator (state, "*", 2); }
| OPERATOR '/'
- { $$ = make_operator ("/", 2); }
+ { $$ = make_operator (state, "/", 2); }
| OPERATOR '%'
- { $$ = make_operator ("%", 2); }
+ { $$ = make_operator (state, "%", 2); }
| OPERATOR '^'
- { $$ = make_operator ("^", 2); }
+ { $$ = make_operator (state, "^", 2); }
| OPERATOR '&'
- { $$ = make_operator ("&", 2); }
+ { $$ = make_operator (state, "&", 2); }
| OPERATOR '|'
- { $$ = make_operator ("|", 2); }
+ { $$ = make_operator (state, "|", 2); }
| OPERATOR '~'
- { $$ = make_operator ("~", 1); }
+ { $$ = make_operator (state, "~", 1); }
| OPERATOR '!'
- { $$ = make_operator ("!", 1); }
+ { $$ = make_operator (state, "!", 1); }
| OPERATOR '='
- { $$ = make_operator ("=", 2); }
+ { $$ = make_operator (state, "=", 2); }
| OPERATOR '<'
- { $$ = make_operator ("<", 2); }
+ { $$ = make_operator (state, "<", 2); }
| OPERATOR '>'
- { $$ = make_operator (">", 2); }
+ { $$ = make_operator (state, ">", 2); }
| OPERATOR ASSIGN_MODIFY
- { $$ = make_operator ($2, 2); }
+ { $$ = make_operator (state, $2, 2); }
| OPERATOR LSH
- { $$ = make_operator ("<<", 2); }
+ { $$ = make_operator (state, "<<", 2); }
| OPERATOR RSH
- { $$ = make_operator (">>", 2); }
+ { $$ = make_operator (state, ">>", 2); }
| OPERATOR EQUAL
- { $$ = make_operator ("==", 2); }
+ { $$ = make_operator (state, "==", 2); }
| OPERATOR NOTEQUAL
- { $$ = make_operator ("!=", 2); }
+ { $$ = make_operator (state, "!=", 2); }
| OPERATOR LEQ
- { $$ = make_operator ("<=", 2); }
+ { $$ = make_operator (state, "<=", 2); }
| OPERATOR GEQ
- { $$ = make_operator (">=", 2); }
+ { $$ = make_operator (state, ">=", 2); }
| OPERATOR ANDAND
- { $$ = make_operator ("&&", 2); }
+ { $$ = make_operator (state, "&&", 2); }
| OPERATOR OROR
- { $$ = make_operator ("||", 2); }
+ { $$ = make_operator (state, "||", 2); }
| OPERATOR INCREMENT
- { $$ = make_operator ("++", 1); }
+ { $$ = make_operator (state, "++", 1); }
| OPERATOR DECREMENT
- { $$ = make_operator ("--", 1); }
+ { $$ = make_operator (state, "--", 1); }
| OPERATOR ','
- { $$ = make_operator (",", 2); }
+ { $$ = make_operator (state, ",", 2); }
| OPERATOR ARROW '*'
- { $$ = make_operator ("->*", 2); }
+ { $$ = make_operator (state, "->*", 2); }
| OPERATOR ARROW
- { $$ = make_operator ("->", 2); }
+ { $$ = make_operator (state, "->", 2); }
| OPERATOR '(' ')'
- { $$ = make_operator ("()", 2); }
+ { $$ = make_operator (state, "()", 2); }
| OPERATOR '[' ']'
- { $$ = make_operator ("[]", 2); }
+ { $$ = make_operator (state, "[]", 2); }
;
/* Conversion operators. We don't try to handle some of
since it's not clear that it's parseable. */
conversion_op
: OPERATOR typespec_2
- { $$ = fill_comp (DEMANGLE_COMPONENT_CONVERSION, $2, NULL); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_CONVERSION, $2, NULL); }
;
conversion_op_name
/* This accepts certain invalid placements of '~'. */
unqualified_name: oper
| oper '<' template_params '>'
- { $$ = fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
| '~' NAME
- { $$ = make_dtor (gnu_v3_complete_object_dtor, $2); }
+ { $$ = make_dtor (state, gnu_v3_complete_object_dtor, $2); }
;
/* This rule is used in name and nested_name, and expanded inline there
;
nested_name : NAME COLONCOLON
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_QUAL_NAME, $1, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_QUAL_NAME, $1, NULL);
$$.last = $$.comp;
}
| nested_name NAME COLONCOLON
{ $$.comp = $1.comp;
- d_right ($1.last) = fill_comp (DEMANGLE_COMPONENT_QUAL_NAME, $2, NULL);
+ d_right ($1.last) = fill_comp (state, DEMANGLE_COMPONENT_QUAL_NAME, $2, NULL);
$$.last = d_right ($1.last);
}
| templ COLONCOLON
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_QUAL_NAME, $1, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_QUAL_NAME, $1, NULL);
$$.last = $$.comp;
}
| nested_name templ COLONCOLON
{ $$.comp = $1.comp;
- d_right ($1.last) = fill_comp (DEMANGLE_COMPONENT_QUAL_NAME, $2, NULL);
+ d_right ($1.last) = fill_comp (state, DEMANGLE_COMPONENT_QUAL_NAME, $2, NULL);
$$.last = d_right ($1.last);
}
;
/* DEMANGLE_COMPONENT_TEMPLATE */
/* DEMANGLE_COMPONENT_TEMPLATE_ARGLIST */
templ : NAME '<' template_params '>'
- { $$ = fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
;
template_params : template_arg
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, $1, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, $1, NULL);
$$.last = &d_right ($$.comp); }
| template_params ',' template_arg
{ $$.comp = $1.comp;
- *$1.last = fill_comp (DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, $3, NULL);
+ *$1.last = fill_comp (state, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, $3, NULL);
$$.last = &d_right (*$1.last);
}
;
*$2.last = $1;
}
| '&' start
- { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $2); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_UNARY, make_operator (state, "&", 1), $2); }
| '&' '(' start ')'
- { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $3); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_UNARY, make_operator (state, "&", 1), $3); }
| exp
;
function_args : typespec_2
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $1, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_ARGLIST, $1, NULL);
$$.last = &d_right ($$.comp);
}
| typespec_2 abstract_declarator
{ *$2.last = $1;
- $$.comp = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $2.comp, NULL);
+ $$.comp = fill_comp (state, DEMANGLE_COMPONENT_ARGLIST, $2.comp, NULL);
$$.last = &d_right ($$.comp);
}
| function_args ',' typespec_2
- { *$1.last = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $3, NULL);
+ { *$1.last = fill_comp (state, DEMANGLE_COMPONENT_ARGLIST, $3, NULL);
$$.comp = $1.comp;
$$.last = &d_right (*$1.last);
}
| function_args ',' typespec_2 abstract_declarator
{ *$4.last = $3;
- *$1.last = fill_comp (DEMANGLE_COMPONENT_ARGLIST, $4.comp, NULL);
+ *$1.last = fill_comp (state, DEMANGLE_COMPONENT_ARGLIST, $4.comp, NULL);
$$.comp = $1.comp;
$$.last = &d_right (*$1.last);
}
| function_args ',' ELLIPSIS
{ *$1.last
- = fill_comp (DEMANGLE_COMPONENT_ARGLIST,
- make_builtin_type ("..."),
+ = fill_comp (state, DEMANGLE_COMPONENT_ARGLIST,
+ make_builtin_type (state, "..."),
NULL);
$$.comp = $1.comp;
$$.last = &d_right (*$1.last);
;
function_arglist: '(' function_args ')' qualifiers_opt %prec NAME
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, $2.comp);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, $2.comp);
$$.last = &d_left ($$.comp);
- $$.comp = d_qualify ($$.comp, $4, 1); }
+ $$.comp = d_qualify (state, $$.comp, $4, 1); }
| '(' VOID ')' qualifiers_opt
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, NULL);
$$.last = &d_left ($$.comp);
- $$.comp = d_qualify ($$.comp, $4, 1); }
+ $$.comp = d_qualify (state, $$.comp, $4, 1); }
| '(' ')' qualifiers_opt
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_FUNCTION_TYPE, NULL, NULL);
$$.last = &d_left ($$.comp);
- $$.comp = d_qualify ($$.comp, $3, 1); }
+ $$.comp = d_qualify (state, $$.comp, $3, 1); }
;
/* Should do something about DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL */
;
builtin_type : int_seq
- { $$ = d_int_type ($1); }
+ { $$ = d_int_type (state, $1); }
| FLOAT_KEYWORD
- { $$ = make_builtin_type ("float"); }
+ { $$ = make_builtin_type (state, "float"); }
| DOUBLE_KEYWORD
- { $$ = make_builtin_type ("double"); }
+ { $$ = make_builtin_type (state, "double"); }
| LONG DOUBLE_KEYWORD
- { $$ = make_builtin_type ("long double"); }
+ { $$ = make_builtin_type (state, "long double"); }
| BOOL
- { $$ = make_builtin_type ("bool"); }
+ { $$ = make_builtin_type (state, "bool"); }
| WCHAR_T
- { $$ = make_builtin_type ("wchar_t"); }
+ { $$ = make_builtin_type (state, "wchar_t"); }
| VOID
- { $$ = make_builtin_type ("void"); }
+ { $$ = make_builtin_type (state, "void"); }
;
ptr_operator : '*' qualifiers_opt
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_POINTER, NULL, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_POINTER, NULL, NULL);
$$.last = &d_left ($$.comp);
- $$.comp = d_qualify ($$.comp, $2, 0); }
+ $$.comp = d_qualify (state, $$.comp, $2, 0); }
/* g++ seems to allow qualifiers after the reference? */
| '&'
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_REFERENCE, NULL, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_REFERENCE, NULL, NULL);
$$.last = &d_left ($$.comp); }
| ANDAND
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_RVALUE_REFERENCE, NULL, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_RVALUE_REFERENCE, NULL, NULL);
$$.last = &d_left ($$.comp); }
| nested_name '*' qualifiers_opt
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_PTRMEM_TYPE, $1.comp, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_PTRMEM_TYPE, $1.comp, NULL);
/* Convert the innermost DEMANGLE_COMPONENT_QUAL_NAME to a DEMANGLE_COMPONENT_NAME. */
*$1.last = *d_left ($1.last);
$$.last = &d_right ($$.comp);
- $$.comp = d_qualify ($$.comp, $3, 0); }
+ $$.comp = d_qualify (state, $$.comp, $3, 0); }
| COLONCOLON nested_name '*' qualifiers_opt
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_PTRMEM_TYPE, $2.comp, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_PTRMEM_TYPE, $2.comp, NULL);
/* Convert the innermost DEMANGLE_COMPONENT_QUAL_NAME to a DEMANGLE_COMPONENT_NAME. */
*$2.last = *d_left ($2.last);
$$.last = &d_right ($$.comp);
- $$.comp = d_qualify ($$.comp, $4, 0); }
+ $$.comp = d_qualify (state, $$.comp, $4, 0); }
;
array_indicator : '[' ']'
- { $$ = fill_comp (DEMANGLE_COMPONENT_ARRAY_TYPE, NULL, NULL); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_ARRAY_TYPE, NULL, NULL); }
| '[' INT ']'
- { $$ = fill_comp (DEMANGLE_COMPONENT_ARRAY_TYPE, $2, NULL); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_ARRAY_TYPE, $2, NULL); }
;
/* Details of this approach inspired by the G++ < 3.4 parser. */
*/
typespec_2 : builtin_type qualifiers
- { $$ = d_qualify ($1, $2, 0); }
+ { $$ = d_qualify (state, $1, $2, 0); }
| builtin_type
| qualifiers builtin_type qualifiers
- { $$ = d_qualify ($2, $1 | $3, 0); }
+ { $$ = d_qualify (state, $2, $1 | $3, 0); }
| qualifiers builtin_type
- { $$ = d_qualify ($2, $1, 0); }
+ { $$ = d_qualify (state, $2, $1, 0); }
| name qualifiers
- { $$ = d_qualify ($1, $2, 0); }
+ { $$ = d_qualify (state, $1, $2, 0); }
| name
| qualifiers name qualifiers
- { $$ = d_qualify ($2, $1 | $3, 0); }
+ { $$ = d_qualify (state, $2, $1 | $3, 0); }
| qualifiers name
- { $$ = d_qualify ($2, $1, 0); }
+ { $$ = d_qualify (state, $2, $1, 0); }
| COLONCOLON name qualifiers
- { $$ = d_qualify ($2, $3, 0); }
+ { $$ = d_qualify (state, $2, $3, 0); }
| COLONCOLON name
{ $$ = $2; }
| qualifiers COLONCOLON name qualifiers
- { $$ = d_qualify ($3, $1 | $4, 0); }
+ { $$ = d_qualify (state, $3, $1 | $4, 0); }
| qualifiers COLONCOLON name
- { $$ = d_qualify ($3, $1, 0); }
+ { $$ = d_qualify (state, $3, $1, 0); }
;
abstract_declarator
$$.last = &d_right ($2);
}
| colon_ext_name
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_TYPED_NAME, $1, NULL);
$$.last = &d_right ($$.comp);
}
;
$$.last = $1.last;
*$2.last = $1.comp; }
| colon_ext_name
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, NULL);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_TYPED_NAME, $1, NULL);
$$.last = &d_right ($$.comp);
}
| direct_declarator_1
members will not be mangled. If they are hopefully
they'll end up to the right of the ::. */
| colon_ext_name function_arglist COLONCOLON start
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
$$.last = $2.last;
- $$.comp = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$.comp, $4);
+ $$.comp = fill_comp (state, DEMANGLE_COMPONENT_LOCAL_NAME, $$.comp, $4);
}
| direct_declarator_1 function_arglist COLONCOLON start
{ $$.comp = $1.comp;
*$1.last = $2.comp;
$$.last = $2.last;
- $$.comp = fill_comp (DEMANGLE_COMPONENT_LOCAL_NAME, $$.comp, $4);
+ $$.comp = fill_comp (state, DEMANGLE_COMPONENT_LOCAL_NAME, $$.comp, $4);
}
;
$$.last = &d_right ($2);
}
| colon_ext_name function_arglist
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_TYPED_NAME, $1, $2.comp);
$$.last = $2.last;
}
| colon_ext_name array_indicator
- { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, $2);
+ { $$.comp = fill_comp (state, DEMANGLE_COMPONENT_TYPED_NAME, $1, $2);
$$.last = &d_right ($2);
}
;
;
exp1 : exp '>' exp
- { $$ = d_binary (">", $1, $3); }
+ { $$ = d_binary (state, ">", $1, $3); }
;
/* References. Not allowed everywhere in template parameters, only
at the top level, but treat them as expressions in case they are wrapped
in parentheses. */
exp1 : '&' start
- { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $2); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_UNARY, make_operator (state, "&", 1), $2); }
| '&' '(' start ')'
- { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $3); }
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_UNARY, make_operator (state, "&", 1), $3); }
;
/* Expressions, not including the comma operator. */
exp : '-' exp %prec UNARY
- { $$ = d_unary ("-", $2); }
+ { $$ = d_unary (state, "-", $2); }
;
exp : '!' exp %prec UNARY
- { $$ = d_unary ("!", $2); }
+ { $$ = d_unary (state, "!", $2); }
;
exp : '~' exp %prec UNARY
- { $$ = d_unary ("~", $2); }
+ { $$ = d_unary (state, "~", $2); }
;
/* Casts. First your normal C-style cast. If exp is a LITERAL, just change
d_left ($4) = $2;
}
else
- $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
- fill_comp (DEMANGLE_COMPONENT_CAST, $2, NULL),
+ $$ = fill_comp (state, DEMANGLE_COMPONENT_UNARY,
+ fill_comp (state, DEMANGLE_COMPONENT_CAST, $2, NULL),
$4);
}
;
/* Mangling does not differentiate between these, so we don't need to
either. */
exp : STATIC_CAST '<' type '>' '(' exp1 ')' %prec UNARY
- { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
- fill_comp (DEMANGLE_COMPONENT_CAST, $3, NULL),
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_UNARY,
+ fill_comp (state, DEMANGLE_COMPONENT_CAST, $3, NULL),
$6);
}
;
exp : DYNAMIC_CAST '<' type '>' '(' exp1 ')' %prec UNARY
- { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
- fill_comp (DEMANGLE_COMPONENT_CAST, $3, NULL),
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_UNARY,
+ fill_comp (state, DEMANGLE_COMPONENT_CAST, $3, NULL),
$6);
}
;
exp : REINTERPRET_CAST '<' type '>' '(' exp1 ')' %prec UNARY
- { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
- fill_comp (DEMANGLE_COMPONENT_CAST, $3, NULL),
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_UNARY,
+ fill_comp (state, DEMANGLE_COMPONENT_CAST, $3, NULL),
$6);
}
;
/* Binary operators in order of decreasing precedence. */
exp : exp '*' exp
- { $$ = d_binary ("*", $1, $3); }
+ { $$ = d_binary (state, "*", $1, $3); }
;
exp : exp '/' exp
- { $$ = d_binary ("/", $1, $3); }
+ { $$ = d_binary (state, "/", $1, $3); }
;
exp : exp '%' exp
- { $$ = d_binary ("%", $1, $3); }
+ { $$ = d_binary (state, "%", $1, $3); }
;
exp : exp '+' exp
- { $$ = d_binary ("+", $1, $3); }
+ { $$ = d_binary (state, "+", $1, $3); }
;
exp : exp '-' exp
- { $$ = d_binary ("-", $1, $3); }
+ { $$ = d_binary (state, "-", $1, $3); }
;
exp : exp LSH exp
- { $$ = d_binary ("<<", $1, $3); }
+ { $$ = d_binary (state, "<<", $1, $3); }
;
exp : exp RSH exp
- { $$ = d_binary (">>", $1, $3); }
+ { $$ = d_binary (state, ">>", $1, $3); }
;
exp : exp EQUAL exp
- { $$ = d_binary ("==", $1, $3); }
+ { $$ = d_binary (state, "==", $1, $3); }
;
exp : exp NOTEQUAL exp
- { $$ = d_binary ("!=", $1, $3); }
+ { $$ = d_binary (state, "!=", $1, $3); }
;
exp : exp LEQ exp
- { $$ = d_binary ("<=", $1, $3); }
+ { $$ = d_binary (state, "<=", $1, $3); }
;
exp : exp GEQ exp
- { $$ = d_binary (">=", $1, $3); }
+ { $$ = d_binary (state, ">=", $1, $3); }
;
exp : exp '<' exp
- { $$ = d_binary ("<", $1, $3); }
+ { $$ = d_binary (state, "<", $1, $3); }
;
exp : exp '&' exp
- { $$ = d_binary ("&", $1, $3); }
+ { $$ = d_binary (state, "&", $1, $3); }
;
exp : exp '^' exp
- { $$ = d_binary ("^", $1, $3); }
+ { $$ = d_binary (state, "^", $1, $3); }
;
exp : exp '|' exp
- { $$ = d_binary ("|", $1, $3); }
+ { $$ = d_binary (state, "|", $1, $3); }
;
exp : exp ANDAND exp
- { $$ = d_binary ("&&", $1, $3); }
+ { $$ = d_binary (state, "&&", $1, $3); }
;
exp : exp OROR exp
- { $$ = d_binary ("||", $1, $3); }
+ { $$ = d_binary (state, "||", $1, $3); }
;
/* Not 100% sure these are necessary, but they're harmless. */
exp : exp ARROW NAME
- { $$ = d_binary ("->", $1, $3); }
+ { $$ = d_binary (state, "->", $1, $3); }
;
exp : exp '.' NAME
- { $$ = d_binary (".", $1, $3); }
+ { $$ = d_binary (state, ".", $1, $3); }
;
exp : exp '?' exp ':' exp %prec '?'
- { $$ = fill_comp (DEMANGLE_COMPONENT_TRINARY, make_operator ("?", 3),
- fill_comp (DEMANGLE_COMPONENT_TRINARY_ARG1, $1,
- fill_comp (DEMANGLE_COMPONENT_TRINARY_ARG2, $3, $5)));
+ { $$ = fill_comp (state, DEMANGLE_COMPONENT_TRINARY, make_operator (state, "?", 3),
+ fill_comp (state, DEMANGLE_COMPONENT_TRINARY_ARG1, $1,
+ fill_comp (state, DEMANGLE_COMPONENT_TRINARY_ARG2, $3, $5)));
}
;
{
/* Match the whitespacing of cplus_demangle_operators.
It would abort on unrecognized string otherwise. */
- $$ = d_unary ("sizeof ", $3);
+ $$ = d_unary (state, "sizeof ", $3);
}
;
/* C++. */
exp : TRUEKEYWORD
{ struct demangle_component *i;
- i = make_name ("1", 1);
- $$ = fill_comp (DEMANGLE_COMPONENT_LITERAL,
- make_builtin_type ("bool"),
+ i = make_name (state, "1", 1);
+ $$ = fill_comp (state, DEMANGLE_COMPONENT_LITERAL,
+ make_builtin_type (state, "bool"),
i);
}
;
exp : FALSEKEYWORD
{ struct demangle_component *i;
- i = make_name ("0", 1);
- $$ = fill_comp (DEMANGLE_COMPONENT_LITERAL,
- make_builtin_type ("bool"),
+ i = make_name (state, "0", 1);
+ $$ = fill_comp (state, DEMANGLE_COMPONENT_LITERAL,
+ make_builtin_type (state, "bool"),
i);
}
;
may already be qualified; duplicate qualifiers are not created. */
struct demangle_component *
-d_qualify (struct demangle_component *lhs, int qualifiers, int is_method)
+d_qualify (cpname_state *state, struct demangle_component *lhs, int qualifiers,
+ int is_method)
{
struct demangle_component **inner_p;
enum demangle_component_type type;
#define HANDLE_QUAL(TYPE, MTYPE, QUAL) \
if ((qualifiers & QUAL) && (type != TYPE) && (type != MTYPE)) \
{ \
- *inner_p = fill_comp (is_method ? MTYPE : TYPE, \
+ *inner_p = fill_comp (state, is_method ? MTYPE : TYPE, \
*inner_p, NULL); \
inner_p = &d_left (*inner_p); \
type = (*inner_p)->type; \
/* Return a builtin type corresponding to FLAGS. */
static struct demangle_component *
-d_int_type (int flags)
+d_int_type (cpname_state *state, int flags)
{
const char *name;
return NULL;
}
- return make_builtin_type (name);
+ return make_builtin_type (state, name);
}
/* Wrapper to create a unary operation. */
static struct demangle_component *
-d_unary (const char *name, struct demangle_component *lhs)
+d_unary (cpname_state *state, const char *name, struct demangle_component *lhs)
{
- return fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator (name, 1), lhs);
+ return fill_comp (state, DEMANGLE_COMPONENT_UNARY, make_operator (state, name, 1), lhs);
}
/* Wrapper to create a binary operation. */
static struct demangle_component *
-d_binary (const char *name, struct demangle_component *lhs, struct demangle_component *rhs)
+d_binary (cpname_state *state, const char *name, struct demangle_component *lhs,
+ struct demangle_component *rhs)
{
- return fill_comp (DEMANGLE_COMPONENT_BINARY, make_operator (name, 2),
- fill_comp (DEMANGLE_COMPONENT_BINARY_ARGS, lhs, rhs));
+ return fill_comp (state, DEMANGLE_COMPONENT_BINARY, make_operator (state, name, 2),
+ fill_comp (state, DEMANGLE_COMPONENT_BINARY_ARGS, lhs, rhs));
}
/* Find the end of a symbol name starting at LEXPTR. */
YYLVAL. */
static int
-parse_number (const char *p, int len, int parsed_float)
+parse_number (cpname_state *state, const char *p, int len, int parsed_float,
+ YYSTYPE *lvalp)
{
int unsigned_p = 0;
if (c == 'f')
{
len--;
- type = make_builtin_type ("float");
+ type = make_builtin_type (state, "float");
}
else if (c == 'l')
{
len--;
- type = make_builtin_type ("long double");
+ type = make_builtin_type (state, "long double");
}
else if (ISDIGIT (c) || c == '.')
- type = make_builtin_type ("double");
+ type = make_builtin_type (state, "double");
else
return ERROR;
- name = make_name (p, len);
- yylval.comp = fill_comp (literal_type, type, name);
+ name = make_name (state, p, len);
+ lvalp->comp = fill_comp (state, literal_type, type, name);
return FLOAT;
}
if (long_p == 0)
{
- unsigned_type = make_builtin_type ("unsigned int");
- signed_type = make_builtin_type ("int");
+ unsigned_type = make_builtin_type (state, "unsigned int");
+ signed_type = make_builtin_type (state, "int");
}
else if (long_p == 1)
{
- unsigned_type = make_builtin_type ("unsigned long");
- signed_type = make_builtin_type ("long");
+ unsigned_type = make_builtin_type (state, "unsigned long");
+ signed_type = make_builtin_type (state, "long");
}
else
{
- unsigned_type = make_builtin_type ("unsigned long long");
- signed_type = make_builtin_type ("long long");
+ unsigned_type = make_builtin_type (state, "unsigned long long");
+ signed_type = make_builtin_type (state, "long long");
}
if (unsigned_p)
else
type = signed_type;
- name = make_name (p, len);
- yylval.comp = fill_comp (literal_type, type, name);
+ name = make_name (state, p, len);
+ lvalp->comp = fill_comp (state, literal_type, type, name);
return INT;
}
#define HANDLE_SPECIAL(string, comp) \
if (strncmp (tokstart, string, sizeof (string) - 1) == 0) \
{ \
- lexptr = tokstart + sizeof (string) - 1; \
- yylval.lval = comp; \
+ state->lexptr = tokstart + sizeof (string) - 1; \
+ lvalp->lval = comp; \
return DEMANGLER_SPECIAL; \
}
#define HANDLE_TOKEN2(string, token) \
- if (lexptr[1] == string[1]) \
+ if (state->lexptr[1] == string[1]) \
{ \
- lexptr += 2; \
- yylval.opname = string; \
+ state->lexptr += 2; \
+ lvalp->opname = string; \
return token; \
}
#define HANDLE_TOKEN3(string, token) \
- if (lexptr[1] == string[1] && lexptr[2] == string[2]) \
+ if (state->lexptr[1] == string[1] && state->lexptr[2] == string[2]) \
{ \
- lexptr += 3; \
- yylval.opname = string; \
+ state->lexptr += 3; \
+ lvalp->opname = string; \
return token; \
}
/* Read one token, getting characters through LEXPTR. */
static int
-yylex (void)
+yylex (YYSTYPE *lvalp, cpname_state *state)
{
int c;
int namelen;
const char *tokstart;
retry:
- prev_lexptr = lexptr;
- tokstart = lexptr;
+ state->prev_lexptr = state->lexptr;
+ tokstart = state->lexptr;
switch (c = *tokstart)
{
case ' ':
case '\t':
case '\n':
- lexptr++;
+ state->lexptr++;
goto retry;
case '\'':
/* We either have a character constant ('0' or '\177' for example)
or we have a quoted symbol reference ('foo(int,int)' in C++
for example). */
- lexptr++;
- c = *lexptr++;
+ state->lexptr++;
+ c = *state->lexptr++;
if (c == '\\')
- c = cp_parse_escape (&lexptr);
+ c = cp_parse_escape (&state->lexptr);
else if (c == '\'')
{
- yyerror (_("empty character constant"));
+ yyerror (state, _("empty character constant"));
return ERROR;
}
- c = *lexptr++;
+ c = *state->lexptr++;
if (c != '\'')
{
- yyerror (_("invalid character constant"));
+ yyerror (state, _("invalid character constant"));
return ERROR;
}
presumably the same one that appears in manglings - the decimal
representation. But if that isn't in our input then we have to
allocate memory for it somewhere. */
- yylval.comp = fill_comp (DEMANGLE_COMPONENT_LITERAL,
- make_builtin_type ("char"),
- make_name (tokstart, lexptr - tokstart));
+ lvalp->comp = fill_comp (state, DEMANGLE_COMPONENT_LITERAL,
+ make_builtin_type (state, "char"),
+ make_name (state, tokstart, state->lexptr - tokstart));
return INT;
case '(':
if (strncmp (tokstart, "(anonymous namespace)", 21) == 0)
{
- lexptr += 21;
- yylval.comp = make_name ("(anonymous namespace)",
+ state->lexptr += 21;
+ lvalp->comp = make_name (state, "(anonymous namespace)",
sizeof "(anonymous namespace)" - 1);
return NAME;
}
case ')':
case ',':
- lexptr++;
+ state->lexptr++;
return c;
case '.':
- if (lexptr[1] == '.' && lexptr[2] == '.')
+ if (state->lexptr[1] == '.' && state->lexptr[2] == '.')
{
- lexptr += 3;
+ state->lexptr += 3;
return ELLIPSIS;
}
/* Might be a floating point number. */
- if (lexptr[1] < '0' || lexptr[1] > '9')
+ if (state->lexptr[1] < '0' || state->lexptr[1] > '9')
goto symbol; /* Nope, must be a symbol. */
goto try_number;
/* For construction vtables. This is kind of hokey. */
if (strncmp (tokstart, "-in-", 4) == 0)
{
- lexptr += 4;
+ state->lexptr += 4;
return CONSTRUCTION_IN;
}
- if (lexptr[1] < '0' || lexptr[1] > '9')
+ if (state->lexptr[1] < '0' || state->lexptr[1] > '9')
{
- lexptr++;
+ state->lexptr++;
return '-';
}
/* FALL THRU. */
else if (! ISALNUM (*p))
break;
}
- toktype = parse_number (tokstart, p - tokstart, got_dot|got_e);
+ toktype = parse_number (state, tokstart, p - tokstart, got_dot|got_e,
+ lvalp);
if (toktype == ERROR)
{
char *err_copy = (char *) alloca (p - tokstart + 1);
memcpy (err_copy, tokstart, p - tokstart);
err_copy[p - tokstart] = 0;
- yyerror (_("invalid number"));
+ yyerror (state, _("invalid number"));
return ERROR;
}
- lexptr = p;
+ state->lexptr = p;
return toktype;
}
case '+':
HANDLE_TOKEN2 ("+=", ASSIGN_MODIFY);
HANDLE_TOKEN2 ("++", INCREMENT);
- lexptr++;
+ state->lexptr++;
return c;
case '*':
HANDLE_TOKEN2 ("*=", ASSIGN_MODIFY);
- lexptr++;
+ state->lexptr++;
return c;
case '/':
HANDLE_TOKEN2 ("/=", ASSIGN_MODIFY);
- lexptr++;
+ state->lexptr++;
return c;
case '%':
HANDLE_TOKEN2 ("%=", ASSIGN_MODIFY);
- lexptr++;
+ state->lexptr++;
return c;
case '|':
HANDLE_TOKEN2 ("|=", ASSIGN_MODIFY);
HANDLE_TOKEN2 ("||", OROR);
- lexptr++;
+ state->lexptr++;
return c;
case '&':
HANDLE_TOKEN2 ("&=", ASSIGN_MODIFY);
HANDLE_TOKEN2 ("&&", ANDAND);
- lexptr++;
+ state->lexptr++;
return c;
case '^':
HANDLE_TOKEN2 ("^=", ASSIGN_MODIFY);
- lexptr++;
+ state->lexptr++;
return c;
case '!':
HANDLE_TOKEN2 ("!=", NOTEQUAL);
- lexptr++;
+ state->lexptr++;
return c;
case '<':
HANDLE_TOKEN3 ("<<=", ASSIGN_MODIFY);
HANDLE_TOKEN2 ("<=", LEQ);
HANDLE_TOKEN2 ("<<", LSH);
- lexptr++;
+ state->lexptr++;
return c;
case '>':
HANDLE_TOKEN3 (">>=", ASSIGN_MODIFY);
HANDLE_TOKEN2 (">=", GEQ);
HANDLE_TOKEN2 (">>", RSH);
- lexptr++;
+ state->lexptr++;
return c;
case '=':
HANDLE_TOKEN2 ("==", EQUAL);
- lexptr++;
+ state->lexptr++;
return c;
case ':':
HANDLE_TOKEN2 ("::", COLONCOLON);
- lexptr++;
+ state->lexptr++;
return c;
case '[':
case '{':
case '}':
symbol:
- lexptr++;
+ state->lexptr++;
return c;
case '"':
/* These can't occur in C++ names. */
- yyerror (_("unexpected string literal"));
+ yyerror (state, _("unexpected string literal"));
return ERROR;
}
if (!(c == '_' || c == '$' || c_ident_is_alpha (c)))
{
/* We must have come across a bad character (e.g. ';'). */
- yyerror (_("invalid character"));
+ yyerror (state, _("invalid character"));
return ERROR;
}
c = tokstart[++namelen];
while (c_ident_is_alnum (c) || c == '_' || c == '$');
- lexptr += namelen;
+ state->lexptr += namelen;
/* Catch specific keywords. Notice that some of the keywords contain
spaces, and are sorted by the length of the first word. They must
case 12:
if (strncmp (tokstart, "construction vtable for ", 24) == 0)
{
- lexptr = tokstart + 24;
+ state->lexptr = tokstart + 24;
return CONSTRUCTION_VTABLE;
}
if (strncmp (tokstart, "dynamic_cast", 12) == 0)
if (strncmp (tokstart, "global constructors keyed to ", 29) == 0)
{
const char *p;
- lexptr = tokstart + 29;
- yylval.lval = DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS;
+ state->lexptr = tokstart + 29;
+ lvalp->lval = DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS;
/* Find the end of the symbol. */
- p = symbol_end (lexptr);
- yylval.comp = make_name (lexptr, p - lexptr);
- lexptr = p;
+ p = symbol_end (state->lexptr);
+ lvalp->comp = make_name (state, state->lexptr, p - state->lexptr);
+ state->lexptr = p;
return DEMANGLER_SPECIAL;
}
if (strncmp (tokstart, "global destructors keyed to ", 28) == 0)
{
const char *p;
- lexptr = tokstart + 28;
- yylval.lval = DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS;
+ state->lexptr = tokstart + 28;
+ lvalp->lval = DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS;
/* Find the end of the symbol. */
- p = symbol_end (lexptr);
- yylval.comp = make_name (lexptr, p - lexptr);
- lexptr = p;
+ p = symbol_end (state->lexptr);
+ lvalp->comp = make_name (state, state->lexptr, p - state->lexptr);
+ state->lexptr = p;
return DEMANGLER_SPECIAL;
}
break;
}
- yylval.comp = make_name (tokstart, namelen);
+ lvalp->comp = make_name (state, tokstart, namelen);
return NAME;
}
static void
-yyerror (const char *msg)
+yyerror (cpname_state *state, const char *msg)
{
- if (global_errmsg)
+ if (state->global_errmsg)
return;
- error_lexptr = prev_lexptr;
- global_errmsg = msg ? msg : "parse error";
+ state->error_lexptr = state->prev_lexptr;
+ state->global_errmsg = msg ? msg : "parse error";
}
/* Allocate a chunk of the components we'll need to build a tree. We
cp_demangled_name_to_comp (const char *demangled_name,
std::string *errmsg)
{
- prev_lexptr = lexptr = demangled_name;
- error_lexptr = NULL;
- global_errmsg = NULL;
+ cpname_state state;
+
+ state.prev_lexptr = state.lexptr = demangled_name;
+ state.error_lexptr = NULL;
+ state.global_errmsg = NULL;
- demangle_info = allocate_info ();
+ state.demangle_info = allocate_info ();
std::unique_ptr<demangle_parse_info> result (new demangle_parse_info);
- result->info = demangle_info;
+ result->info = state.demangle_info;
- if (yyparse ())
+ if (yyparse (&state))
{
- if (global_errmsg && errmsg)
- *errmsg = string_printf ("%s, near `%s'", global_errmsg,
- error_lexptr);
+ if (state.global_errmsg && errmsg)
+ *errmsg = state.global_errmsg;
return NULL;
}
- result->tree = global_result;
- global_result = NULL;
+ result->tree = state.global_result;
return result;
}