C++-ify parser_state

This mildly C++-ifies parser_state and stap_parse_info -- just enough
to remove some cleanups.

This version includes the changes implemented by Simon.

Regression tested by the buildbot.

gdb/ChangeLog
2017-12-30  Tom Tromey  <tom@tromey.com>
	    Simon Marchi  <simon.marchi@ericsson.com>

	* stap-probe.h (struct stap_parse_info): Add constructor,
	destructor.
	* stap-probe.c (stap_parse_argument): Update.
	* rust-exp.y (rust_lex_tests): Update.
	* parser-defs.h (struct parser_state): Add constructor,
	destructor, release method.
	<expout>: Change type to expression_up.
	(null_post_parser): Change type.
	(initialize_expout, reallocate_expout): Remove.
	* parse.c (parser_state::parser_state): Rename from
	initialize_expout.
	(parser_state::release): Rename from reallocate_expout.
	(write_exp_elt, parse_exp_in_context_1, increase_expout_size):
	Update.
	(null_post_parser): Change type of "exp".
	* dtrace-probe.c (dtrace_probe::build_arg_exprs): Update.
	* ada-lang.c (resolve, resolve_subexp)
	(replace_operator_with_call): Change type of "expp".
	* language.h (struct language_defn) <la_post_parser>: Change type
	of "expp".
This commit is contained in:
Tom Tromey
2017-11-22 21:45:53 -07:00
parent a594729cfb
commit e9d9f57e11
9 changed files with 110 additions and 102 deletions

View File

@ -1,3 +1,27 @@
2017-12-30 Tom Tromey <tom@tromey.com>
Simon Marchi <simon.marchi@ericsson.com>
* stap-probe.h (struct stap_parse_info): Add constructor,
destructor.
* stap-probe.c (stap_parse_argument): Update.
* rust-exp.y (rust_lex_tests): Update.
* parser-defs.h (struct parser_state): Add constructor,
destructor, release method.
<expout>: Change type to expression_up.
(null_post_parser): Change type.
(initialize_expout, reallocate_expout): Remove.
* parse.c (parser_state::parser_state): Rename from
initialize_expout.
(parser_state::release): Rename from reallocate_expout.
(write_exp_elt, parse_exp_in_context_1, increase_expout_size):
Update.
(null_post_parser): Change type of "exp".
* dtrace-probe.c (dtrace_probe::build_arg_exprs): Update.
* ada-lang.c (resolve, resolve_subexp)
(replace_operator_with_call): Change type of "expp".
* language.h (struct language_defn) <la_post_parser>: Change type
of "expp".
2017-12-30 Simon Marchi <simon.marchi@ericsson.com> 2017-12-30 Simon Marchi <simon.marchi@ericsson.com>
* dwarf2read.c (struct mapped_debug_names): Make final. * dwarf2read.c (struct mapped_debug_names): Make final.

View File

@ -124,10 +124,10 @@ static int num_defns_collected (struct obstack *);
static struct block_symbol *defns_collected (struct obstack *, int); static struct block_symbol *defns_collected (struct obstack *, int);
static struct value *resolve_subexp (struct expression **, int *, int, static struct value *resolve_subexp (expression_up *, int *, int,
struct type *); struct type *);
static void replace_operator_with_call (struct expression **, int, int, int, static void replace_operator_with_call (expression_up *, int, int, int,
struct symbol *, const struct block *); struct symbol *, const struct block *);
static int possible_user_operator_p (enum exp_opcode, struct value **); static int possible_user_operator_p (enum exp_opcode, struct value **);
@ -3235,7 +3235,7 @@ ada_decoded_op_name (enum exp_opcode op)
return type is preferred. May change (expand) *EXP. */ return type is preferred. May change (expand) *EXP. */
static void static void
resolve (struct expression **expp, int void_context_p) resolve (expression_up *expp, int void_context_p)
{ {
struct type *context_type = NULL; struct type *context_type = NULL;
int pc = 0; int pc = 0;
@ -3256,7 +3256,7 @@ resolve (struct expression **expp, int void_context_p)
are as in ada_resolve, above. */ are as in ada_resolve, above. */
static struct value * static struct value *
resolve_subexp (struct expression **expp, int *pos, int deprocedure_p, resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
struct type *context_type) struct type *context_type)
{ {
int pc = *pos; int pc = *pos;
@ -3270,7 +3270,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
argvec = NULL; argvec = NULL;
nargs = 0; nargs = 0;
exp = *expp; exp = expp->get ();
/* Pass one: resolve operands, saving their types and updating *pos, /* Pass one: resolve operands, saving their types and updating *pos,
if needed. */ if needed. */
@ -3420,7 +3420,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
for (i = 0; i < nargs; i += 1) for (i = 0; i < nargs; i += 1)
argvec[i] = resolve_subexp (expp, pos, 1, NULL); argvec[i] = resolve_subexp (expp, pos, 1, NULL);
argvec[i] = NULL; argvec[i] = NULL;
exp = *expp; exp = expp->get ();
/* Pass two: perform any resolution on principal operator. */ /* Pass two: perform any resolution on principal operator. */
switch (op) switch (op)
@ -3515,7 +3515,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
replace_operator_with_call (expp, pc, 0, 0, replace_operator_with_call (expp, pc, 0, 0,
exp->elts[pc + 2].symbol, exp->elts[pc + 2].symbol,
exp->elts[pc + 1].block); exp->elts[pc + 1].block);
exp = *expp; exp = expp->get ();
} }
break; break;
@ -3596,7 +3596,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p,
replace_operator_with_call (expp, pc, nargs, 1, replace_operator_with_call (expp, pc, nargs, 1,
candidates[i].symbol, candidates[i].symbol,
candidates[i].block); candidates[i].block);
exp = *expp; exp = expp->get ();
} }
break; break;
@ -4115,7 +4115,7 @@ get_selections (int *choices, int n_choices, int max_results,
arguments. Update *EXPP as needed to hold more space. */ arguments. Update *EXPP as needed to hold more space. */
static void static void
replace_operator_with_call (struct expression **expp, int pc, int nargs, replace_operator_with_call (expression_up *expp, int pc, int nargs,
int oplen, struct symbol *sym, int oplen, struct symbol *sym,
const struct block *block) const struct block *block)
{ {
@ -4124,7 +4124,7 @@ replace_operator_with_call (struct expression **expp, int pc, int nargs,
struct expression *newexp = (struct expression *) struct expression *newexp = (struct expression *)
xzalloc (sizeof (struct expression) xzalloc (sizeof (struct expression)
+ EXP_ELEM_TO_BYTES ((*expp)->nelts + 7 - oplen)); + EXP_ELEM_TO_BYTES ((*expp)->nelts + 7 - oplen));
struct expression *exp = *expp; struct expression *exp = expp->get ();
newexp->nelts = exp->nelts + 7 - oplen; newexp->nelts = exp->nelts + 7 - oplen;
newexp->language_defn = exp->language_defn; newexp->language_defn = exp->language_defn;
@ -4140,8 +4140,7 @@ replace_operator_with_call (struct expression **expp, int pc, int nargs,
newexp->elts[pc + 4].block = block; newexp->elts[pc + 4].block = block;
newexp->elts[pc + 5].symbol = sym; newexp->elts[pc + 5].symbol = sym;
*expp = newexp; expp->reset (newexp);
xfree (exp);
} }
/* Type-class predicates */ /* Type-class predicates */

View File

@ -625,21 +625,15 @@ dtrace_probe::build_arg_exprs (struct gdbarch *gdbarch)
value of the argument when executed at the PC of the probe. */ value of the argument when executed at the PC of the probe. */
for (dtrace_probe_arg &arg : m_args) for (dtrace_probe_arg &arg : m_args)
{ {
struct cleanup *back_to;
struct parser_state pstate;
/* Initialize the expression buffer in the parser state. The /* Initialize the expression buffer in the parser state. The
language does not matter, since we are using our own language does not matter, since we are using our own
parser. */ parser. */
initialize_expout (&pstate, 10, current_language, gdbarch); parser_state pstate (10, current_language, gdbarch);
back_to = make_cleanup (free_current_contents, &pstate.expout);
/* The argument value, which is ABI dependent and casted to /* The argument value, which is ABI dependent and casted to
`long int'. */ `long int'. */
gdbarch_dtrace_parse_probe_argument (gdbarch, &pstate, argc); gdbarch_dtrace_parse_probe_argument (gdbarch, &pstate, argc);
discard_cleanups (back_to);
/* Casting to the expected type, but only if the type was /* Casting to the expected type, but only if the type was
recognized at probe load time. Otherwise the argument will recognized at probe load time. Otherwise the argument will
be evaluated as the long integer passed to the probe. */ be evaluated as the long integer passed to the probe. */
@ -650,8 +644,7 @@ dtrace_probe::build_arg_exprs (struct gdbarch *gdbarch)
write_exp_elt_opcode (&pstate, UNOP_CAST); write_exp_elt_opcode (&pstate, UNOP_CAST);
} }
reallocate_expout (&pstate); arg.expr = pstate.release ();
arg.expr = expression_up (pstate.expout);
prefixify_expression (arg.expr.get ()); prefixify_expression (arg.expr.get ());
++argc; ++argc;
} }

View File

@ -25,12 +25,12 @@
#include "symtab.h" #include "symtab.h"
#include "common/function-view.h" #include "common/function-view.h"
#include "expression.h"
/* Forward decls for prototypes. */ /* Forward decls for prototypes. */
struct value; struct value;
struct objfile; struct objfile;
struct frame_info; struct frame_info;
struct expression;
struct ui_file; struct ui_file;
struct value_print_options; struct value_print_options;
struct type_print_options; struct type_print_options;
@ -182,7 +182,7 @@ struct language_defn
for releasing its previous contents, if necessary. If for releasing its previous contents, if necessary. If
VOID_CONTEXT_P, then no value is expected from the expression. */ VOID_CONTEXT_P, then no value is expected from the expression. */
void (*la_post_parser) (struct expression ** expp, int void_context_p); void (*la_post_parser) (expression_up *expp, int void_context_p);
void (*la_printchar) (int ch, struct type *chtype, void (*la_printchar) (int ch, struct type *chtype,
struct ui_file * stream); struct ui_file * stream);

View File

@ -152,34 +152,32 @@ end_arglist (void)
/* See definition in parser-defs.h. */ /* See definition in parser-defs.h. */
void parser_state::parser_state (size_t initial_size,
initialize_expout (struct parser_state *ps, size_t initial_size, const struct language_defn *lang,
const struct language_defn *lang, struct gdbarch *gdbarch)
struct gdbarch *gdbarch) : expout_size (initial_size),
expout (XNEWVAR (expression,
(sizeof (expression)
+ EXP_ELEM_TO_BYTES (expout_size)))),
expout_ptr (0)
{ {
ps->expout_size = initial_size; expout->language_defn = lang;
ps->expout_ptr = 0; expout->gdbarch = gdbarch;
ps->expout
= (struct expression *) xmalloc (sizeof (struct expression)
+ EXP_ELEM_TO_BYTES (ps->expout_size));
ps->expout->language_defn = lang;
ps->expout->gdbarch = gdbarch;
} }
/* See definition in parser-defs.h. */ expression_up
parser_state::release ()
void
reallocate_expout (struct parser_state *ps)
{ {
/* Record the actual number of expression elements, and then /* Record the actual number of expression elements, and then
reallocate the expression memory so that we free up any reallocate the expression memory so that we free up any
excess elements. */ excess elements. */
ps->expout->nelts = ps->expout_ptr; expout->nelts = expout_ptr;
ps->expout = (struct expression *) expout.reset (XRESIZEVAR (expression, expout.release (),
xrealloc (ps->expout, (sizeof (expression)
sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_ptr))));
+ EXP_ELEM_TO_BYTES (ps->expout_ptr));
return std::move (expout);
} }
/* This page contains the functions for adding data to the struct expression /* This page contains the functions for adding data to the struct expression
@ -196,9 +194,9 @@ write_exp_elt (struct parser_state *ps, const union exp_element *expelt)
if (ps->expout_ptr >= ps->expout_size) if (ps->expout_ptr >= ps->expout_size)
{ {
ps->expout_size *= 2; ps->expout_size *= 2;
ps->expout = (struct expression *) ps->expout.reset (XRESIZEVAR (expression, ps->expout.release (),
xrealloc (ps->expout, sizeof (struct expression) (sizeof (expression)
+ EXP_ELEM_TO_BYTES (ps->expout_size)); + EXP_ELEM_TO_BYTES (ps->expout_size))));
} }
ps->expout->elts[ps->expout_ptr++] = *expelt; ps->expout->elts[ps->expout_ptr++] = *expelt;
} }
@ -1116,7 +1114,6 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
int comma, int void_context_p, int *out_subexp) int comma, int void_context_p, int *out_subexp)
{ {
const struct language_defn *lang = NULL; const struct language_defn *lang = NULL;
struct parser_state ps;
int subexp; int subexp;
lexptr = *stringptr; lexptr = *stringptr;
@ -1192,7 +1189,7 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
and others called from *.y) ensure CURRENT_LANGUAGE gets restored and others called from *.y) ensure CURRENT_LANGUAGE gets restored
to the value matching SELECTED_FRAME as set by get_current_arch. */ to the value matching SELECTED_FRAME as set by get_current_arch. */
initialize_expout (&ps, 10, lang, get_current_arch ()); parser_state ps (10, lang, get_current_arch ());
scoped_restore_current_language lang_saver; scoped_restore_current_language lang_saver;
set_language (lang->la_language); set_language (lang->la_language);
@ -1205,33 +1202,32 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
if (! parse_completion) if (! parse_completion)
{ throw_exception (except);
xfree (ps.expout);
throw_exception (except);
}
} }
END_CATCH END_CATCH
reallocate_expout (&ps); /* We have to operate on an "expression *", due to la_post_parser,
which explains this funny-looking double release. */
expression_up result = ps.release ();
/* Convert expression from postfix form as generated by yacc /* Convert expression from postfix form as generated by yacc
parser, to a prefix form. */ parser, to a prefix form. */
if (expressiondebug) if (expressiondebug)
dump_raw_expression (ps.expout, gdb_stdlog, dump_raw_expression (result.get (), gdb_stdlog,
"before conversion to prefix form"); "before conversion to prefix form");
subexp = prefixify_expression (ps.expout); subexp = prefixify_expression (result.get ());
if (out_subexp) if (out_subexp)
*out_subexp = subexp; *out_subexp = subexp;
lang->la_post_parser (&ps.expout, void_context_p); lang->la_post_parser (&result, void_context_p);
if (expressiondebug) if (expressiondebug)
dump_prefix_expression (ps.expout, gdb_stdlog); dump_prefix_expression (result.get (), gdb_stdlog);
*stringptr = lexptr; *stringptr = lexptr;
return expression_up (ps.expout); return result;
} }
/* Parse STRING as an expression, and complain if this fails /* Parse STRING as an expression, and complain if this fails
@ -1320,7 +1316,7 @@ parse_expression_for_completion (const char *string, char **name,
/* A post-parser that does nothing. */ /* A post-parser that does nothing. */
void void
null_post_parser (struct expression **exp, int void_context_p) null_post_parser (expression_up *exp, int void_context_p)
{ {
} }
@ -1866,10 +1862,11 @@ increase_expout_size (struct parser_state *ps, size_t lenelt)
if ((ps->expout_ptr + lenelt) >= ps->expout_size) if ((ps->expout_ptr + lenelt) >= ps->expout_size)
{ {
ps->expout_size = std::max (ps->expout_size * 2, ps->expout_size = std::max (ps->expout_size * 2,
ps->expout_ptr + lenelt + 10); ps->expout_ptr + lenelt + 10);
ps->expout = (struct expression *) ps->expout.reset (XRESIZEVAR (expression,
xrealloc (ps->expout, (sizeof (struct expression) ps->expout.release (),
+ EXP_ELEM_TO_BYTES (ps->expout_size))); (sizeof (struct expression)
+ EXP_ELEM_TO_BYTES (ps->expout_size))));
} }
} }

View File

@ -37,14 +37,27 @@ extern int parser_debug;
struct parser_state struct parser_state
{ {
/* The expression related to this parser state. */ /* Constructor. INITIAL_SIZE is the initial size of the expout
array. LANG is the language used to parse the expression. And
GDBARCH is the gdbarch to use during parsing. */
struct expression *expout; parser_state (size_t initial_size, const struct language_defn *lang,
struct gdbarch *gdbarch);
DISABLE_COPY_AND_ASSIGN (parser_state);
/* Resize the allocated expression to the correct size, and return
it as an expression_up -- passing ownership to the caller. */
expression_up release ();
/* The size of the expression above. */ /* The size of the expression above. */
size_t expout_size; size_t expout_size;
/* The expression related to this parser state. */
expression_up expout;
/* The number of elements already in the expression. This is used /* The number of elements already in the expression. This is used
to know where to put new elements. */ to know where to put new elements. */
@ -156,23 +169,6 @@ struct type_stack
int size; int size;
}; };
/* Helper function to initialize the expout, expout_size, expout_ptr
trio inside PS before it is used to store expression elements created
during the parsing of an expression. INITIAL_SIZE is the initial size of
the expout array. LANG is the language used to parse the expression.
And GDBARCH is the gdbarch to use during parsing. */
extern void initialize_expout (struct parser_state *ps,
size_t initial_size,
const struct language_defn *lang,
struct gdbarch *gdbarch);
/* Helper function that reallocates the EXPOUT inside PS in order to
eliminate any unused space. It is generally used when the expression
has just been parsed and created. */
extern void reallocate_expout (struct parser_state *ps);
/* Reverse an expression from suffix form (in which it is constructed) /* Reverse an expression from suffix form (in which it is constructed)
to prefix form (in which we can conveniently print or execute it). to prefix form (in which we can conveniently print or execute it).
Ordinarily this always returns -1. However, if EXPOUT_LAST_STRUCT Ordinarily this always returns -1. However, if EXPOUT_LAST_STRUCT
@ -265,7 +261,7 @@ extern struct type *follow_types (struct type *);
extern type_instance_flags follow_type_instance_flags (); extern type_instance_flags follow_type_instance_flags ();
extern void null_post_parser (struct expression **, int); extern void null_post_parser (expression_up *, int);
extern bool parse_float (const char *p, int len, extern bool parse_float (const char *p, int len,
const struct type *type, gdb_byte *data); const struct type *type, gdb_byte *data);

View File

@ -2666,8 +2666,7 @@ rust_lex_tests (void)
&test_obstack); &test_obstack);
// Set up dummy "parser", so that rust_type works. // Set up dummy "parser", so that rust_type works.
struct parser_state ps; struct parser_state ps (0, &rust_language_defn, target_gdbarch ());
initialize_expout (&ps, 0, &rust_language_defn, target_gdbarch ());
rust_parser parser (&ps); rust_parser parser (&ps);
rust_lex_test_one ("", 0); rust_lex_test_one ("", 0);

View File

@ -1146,25 +1146,14 @@ static expression_up
stap_parse_argument (const char **arg, struct type *atype, stap_parse_argument (const char **arg, struct type *atype,
struct gdbarch *gdbarch) struct gdbarch *gdbarch)
{ {
struct stap_parse_info p;
struct cleanup *back_to;
/* We need to initialize the expression buffer, in order to begin /* We need to initialize the expression buffer, in order to begin
our parsing efforts. We use language_c here because we may need our parsing efforts. We use language_c here because we may need
to do pointer arithmetics. */ to do pointer arithmetics. */
initialize_expout (&p.pstate, 10, language_def (language_c), gdbarch); struct stap_parse_info p (*arg, atype, 10, language_def (language_c),
back_to = make_cleanup (free_current_contents, &p.pstate.expout); gdbarch);
p.saved_arg = *arg;
p.arg = *arg;
p.arg_type = atype;
p.gdbarch = gdbarch;
p.inside_paren_p = 0;
stap_parse_argument_1 (&p, 0, STAP_OPERAND_PREC_NONE); stap_parse_argument_1 (&p, 0, STAP_OPERAND_PREC_NONE);
discard_cleanups (back_to);
gdb_assert (p.inside_paren_p == 0); gdb_assert (p.inside_paren_p == 0);
/* Casting the final expression to the appropriate type. */ /* Casting the final expression to the appropriate type. */
@ -1172,13 +1161,10 @@ stap_parse_argument (const char **arg, struct type *atype,
write_exp_elt_type (&p.pstate, atype); write_exp_elt_type (&p.pstate, atype);
write_exp_elt_opcode (&p.pstate, UNOP_CAST); write_exp_elt_opcode (&p.pstate, UNOP_CAST);
reallocate_expout (&p.pstate);
p.arg = skip_spaces (p.arg); p.arg = skip_spaces (p.arg);
*arg = p.arg; *arg = p.arg;
/* We can safely return EXPOUT here. */ return p.pstate.release ();
return expression_up (p.pstate.expout);
} }
/* Implementation of 'parse_arguments' method. */ /* Implementation of 'parse_arguments' method. */

View File

@ -28,6 +28,20 @@
struct stap_parse_info struct stap_parse_info
{ {
stap_parse_info (const char *arg_, struct type *arg_type_,
size_t initial_size, const struct language_defn *lang,
struct gdbarch *gdbarch)
: arg (arg_),
pstate (initial_size, lang, gdbarch),
saved_arg (arg_),
arg_type (arg_type_),
gdbarch (gdbarch),
inside_paren_p (0)
{
}
DISABLE_COPY_AND_ASSIGN (stap_parse_info);
/* The probe's argument in a string format. */ /* The probe's argument in a string format. */
const char *arg; const char *arg;