Re: [RFC 1/8] Language independent bits

Jan Kratochvil
2012-01-15T21:17:57Z

On Sun, 15 Jan 2012 22:07:30 +0100, Sergio Durigan Junior wrote:
> By "these two functions" you mean on `unk_lang_error' and
> `unk_lang_parser'?

Yes.

> If so, then the answer is "no", but I still need to
> pass `ps' because of the prototype of `la_parser' and `la_error'.

OK, sorry.

> >> + ps->expout = (struct expression *)
> >> + xmalloc (sizeof (struct expression)
> >> + + EXP_ELEM_TO_BYTES (ps->expout_size));
> >
> > That return type cast is excessive. It had meaning for K&R C where xmalloc
> > returns PTR but that is no longer supported. There should be done
> > s/PTR/void */ everywhere and #define PTR should be removed
> > and #pragma GCC poison -ed.
>
> Sorry, I am not sure I understood your argument.

I do not understand why you put that cast in.

void * clearly does not need casting to struct expression *, it is compatible
in the assignment. I thought you may think xmalloc may return also char *
during some builds so I was assuring you this cannot happen anymore.

Another reason may be you are used to it from C++. But GDB is not in C++ now.
If/when it will be it can be changed easily, I do not think we should write in
C++ already when it is not built as C++ yet, if ever. But I would not mind
this reason much, I expected more the PTR (char *) reason.

> If you mean I should
> remove the cast to `struct expression *', then OK, I can do that.

Yes, thanks.

>
> This is the updated patch, which addresses the issues you have pointed.
> Thanks for the comments.
>
> Sergio.
>
> ---
> gdb/language.c | 8 +-
> gdb/language.h | 5 +-
> gdb/parse.c | 295 ++++++++++++++++++++++++++++-------------------------
> gdb/parser-defs.h | 63 ++++++++----
> 4 files changed, 205 insertions(+), 166 deletions(-)
>
> diff --git a/gdb/language.c b/gdb/language.c
> index d70ae81..b02fc5b 100644
> --- a/gdb/language.c
> +++ b/gdb/language.c
> @@ -47,9 +47,9 @@
>
> extern void _initialize_language (void);
>
> -static void unk_lang_error (char *);
> +static void unk_lang_error (struct parser_state *, char *);
>
> -static int unk_lang_parser (void);
> +static int unk_lang_parser (struct parser_state *);
>
> static void show_check (char *, int);
>
> @@ -803,13 +803,13 @@ default_get_string (struct value *value, gdb_byte **buffer, int *length,
> /* Define the language that is no language. */
>
> static int
> -unk_lang_parser (void)
> +unk_lang_parser (struct parser_state *ps)
> {
> return 1;
> }
>
> static void
> -unk_lang_error (char *msg)
> +unk_lang_error (struct parser_state *ps, char *msg)
> {
> error (_("Attempted to parse an expression with unknown language"));
> }
> diff --git a/gdb/language.h b/gdb/language.h
> index 2ea2dca..6faf9c7 100644
> --- a/gdb/language.h
> +++ b/gdb/language.h
> @@ -31,6 +31,7 @@ struct frame_info;
> struct expression;
> struct ui_file;
> struct value_print_options;
> +struct parser_state;
>
> #define MAX_FORTRAN_DIMS 7 /* Maximum number of F77 array dims. */
>
> @@ -172,11 +173,11 @@ struct language_defn
>
> /* Parser function. */
>
> - int (*la_parser) (void);
> + int (*la_parser) (struct parser_state *);
>
> /* Parser error function. */
>
> - void (*la_error) (char *);
> + void (*la_error) (struct parser_state *, char *);
>
> /* Given an expression *EXPP created by prefixifying the result of
> la_parser, perform any remaining processing necessary to complete
> diff --git a/gdb/parse.c b/gdb/parse.c
> index f405dc5..7f154b3 100644
> --- a/gdb/parse.c
> +++ b/gdb/parse.c
> @@ -68,9 +68,6 @@ const struct exp_descriptor exp_descriptor_standard =
> };
> \f
> /* Global variables declared in parser-defs.h (and commented there). */
> -struct expression *expout;
> -int expout_size;
> -int expout_ptr;
> struct block *expression_context_block;
> CORE_ADDR expression_context_pc;
> struct block *innermost_block;
> @@ -179,6 +176,44 @@ free_funcalls (void *ignore)
> }
> }
> \f
> +
> +/* Helper function used to initialize an struct expression that is going
> + to be used to store expression elements. The arguments are the
> + parser_state PS containing the EXPOUT, the INITIAL_SIZE of the expression,
> + the language LANG parsed to build this expression, and the GDBARCH
> + pointer. */
> +
> +static void
> +initialize_expout (struct parser_state *ps, size_t initial_size,
> + const struct language_defn *lang,
> + struct gdbarch *gdbarch)
> +{
> + ps->expout_size = initial_size;
> + ps->expout_ptr = 0;
> + ps->expout = xmalloc (sizeof (struct expression)
> + + EXP_ELEM_TO_BYTES (ps->expout_size));
> + ps->expout->language_defn = lang;
> + ps->expout->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. */
> +
> +static void
> +reallocate_expout (struct parser_state *ps)
> +{
> + /* Record the actual number of expression elements, and then
> + reallocate the expression memory so that we free up any
> + excess elements. */
> +
> + ps->expout->nelts = ps->expout_ptr;
> + ps->expout = (struct expression *)
> + xrealloc (ps->expout,
> + sizeof (struct expression)
> + + EXP_ELEM_TO_BYTES (ps->expout_ptr));
> +}
> +
> /* This page contains the functions for adding data to the struct expression
> being constructed. */
>
> @@ -188,80 +223,80 @@ free_funcalls (void *ignore)
> a register through here. */
>
> static void
> -write_exp_elt (const union exp_element *expelt)
> +write_exp_elt (struct parser_state *ps, const union exp_element *expelt)
> {
> - if (expout_ptr >= expout_size)
> + if (ps->expout_ptr >= ps->expout_size)
> {
> - expout_size *= 2;
> - expout = (struct expression *)
> - xrealloc ((char *) expout, sizeof (struct expression)
> - + EXP_ELEM_TO_BYTES (expout_size));
> + ps->expout_size *= 2;
> + ps->expout = (struct expression *)
> + xrealloc (ps->expout, sizeof (struct expression)
> + + EXP_ELEM_TO_BYTES (ps->expout_size));
> }
> - expout->elts[expout_ptr++] = *expelt;
> + ps->expout->elts[ps->expout_ptr++] = *expelt;
> }
>
> void
> -write_exp_elt_opcode (enum exp_opcode expelt)
> +write_exp_elt_opcode (struct parser_state *ps, enum exp_opcode expelt)
> {
> union exp_element tmp;
>
> memset (&tmp, 0, sizeof (union exp_element));
> tmp.opcode = expelt;
> - write_exp_elt (&tmp);
> + write_exp_elt (ps, &tmp);
> }
>
> void
> -write_exp_elt_sym (struct symbol *expelt)
> +write_exp_elt_sym (struct parser_state *ps, struct symbol *expelt)
> {
> union exp_element tmp;
>
> memset (&tmp, 0, sizeof (union exp_element));
> tmp.symbol = expelt;
> - write_exp_elt (&tmp);
> + write_exp_elt (ps, &tmp);
> }
>
> void
> -write_exp_elt_block (struct block *b)
> +write_exp_elt_block (struct parser_state *ps, struct block *b)
> {
> union exp_element tmp;
>
> memset (&tmp, 0, sizeof (union exp_element));
> tmp.block = b;
> - write_exp_elt (&tmp);
> + write_exp_elt (ps, &tmp);
> }
>
> void
> -write_exp_elt_objfile (struct objfile *objfile)
> +write_exp_elt_objfile (struct parser_state *ps, struct objfile *objfile)
> {
> union exp_element tmp;
>
> memset (&tmp, 0, sizeof (union exp_element));
> tmp.objfile = objfile;
> - write_exp_elt (&tmp);
> + write_exp_elt (ps, &tmp);
> }
>
> void
> -write_exp_elt_longcst (LONGEST expelt)
> +write_exp_elt_longcst (struct parser_state *ps, LONGEST expelt)
> {
> union exp_element tmp;
>
> memset (&tmp, 0, sizeof (union exp_element));
> tmp.longconst = expelt;
> - write_exp_elt (&tmp);
> + write_exp_elt (ps, &tmp);
> }
>
> void
> -write_exp_elt_dblcst (DOUBLEST expelt)
> +write_exp_elt_dblcst (struct parser_state *ps, DOUBLEST expelt)
> {
> union exp_element tmp;
>
> memset (&tmp, 0, sizeof (union exp_element));
> tmp.doubleconst = expelt;
> - write_exp_elt (&tmp);
> + write_exp_elt (ps, &tmp);
> }
>
> void
> -write_exp_elt_decfloatcst (gdb_byte expelt[16])
> +write_exp_elt_decfloatcst (struct parser_state *ps, gdb_byte expelt[16])
> {
> union exp_element tmp;
> int index;
> @@ -269,27 +304,27 @@ write_exp_elt_decfloatcst (gdb_byte expelt[16])
> for (index = 0; index < 16; index++)
> tmp.decfloatconst[index] = expelt[index];
>
> - write_exp_elt (&tmp);
> + write_exp_elt (ps, &tmp);
> }
>
> void
> -write_exp_elt_type (struct type *expelt)
> +write_exp_elt_type (struct parser_state *ps, struct type *expelt)
> {
> union exp_element tmp;
>
> memset (&tmp, 0, sizeof (union exp_element));
> tmp.type = expelt;
> - write_exp_elt (&tmp);
> + write_exp_elt (ps, &tmp);
> }
>
> void
> -write_exp_elt_intern (struct internalvar *expelt)
> +write_exp_elt_intern (struct parser_state *ps, struct internalvar *expelt)
> {
> union exp_element tmp;
>
> memset (&tmp, 0, sizeof (union exp_element));
> tmp.internalvar = expelt;
> - write_exp_elt (&tmp);
> + write_exp_elt (ps, &tmp);
> }
>
> /* Add a string constant to the end of the expression.
> @@ -314,10 +349,10 @@ write_exp_elt_intern (struct internalvar *expelt)
>
>
> void
> -write_exp_string (struct stoken str)
> +write_exp_string (struct parser_state *ps, struct stoken str)
> {
> int len = str.length;
> - int lenelt;
> + size_t lenelt;
> char *strdata;
>
> /* Compute the number of expression elements required to hold the string
> @@ -327,28 +362,19 @@ write_exp_string (struct stoken str)
>
> lenelt = 2 + BYTES_TO_EXP_ELEM (len + 1);
>
> - /* Ensure that we have enough available expression elements to store
> - everything. */
> -
> - if ((expout_ptr + lenelt) >= expout_size)
> - {
> - expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
> - expout = (struct expression *)
> - xrealloc ((char *) expout, (sizeof (struct expression)
> - + EXP_ELEM_TO_BYTES (expout_size)));
> - }
> + increase_expout_size (ps, lenelt);
>
> /* Write the leading length expression element (which advances the current
> expression element index), then write the string constant followed by a
> terminating null byte, and then write the trailing length expression
> element. */
>
> - write_exp_elt_longcst ((LONGEST) len);
> - strdata = (char *) &expout->elts[expout_ptr];
> + write_exp_elt_longcst (ps, (LONGEST) len);
> + strdata = (char *) &ps->expout->elts[ps->expout_ptr];
> memcpy (strdata, str.ptr, len);
> *(strdata + len) = '\0';
> - expout_ptr += lenelt - 2;
> - write_exp_elt_longcst ((LONGEST) len);
> + ps->expout_ptr += lenelt - 2;
> + write_exp_elt_longcst (ps, (LONGEST) len);
> }
>
> /* Add a vector of string constants to the end of the expression.
> @@ -365,9 +391,11 @@ write_exp_string (struct stoken str)
> long constant, followed by the contents of the string. */
>
> void
> -write_exp_string_vector (int type, struct stoken_vector *vec)
> +write_exp_string_vector (struct parser_state *ps, int type,
> + struct stoken_vector *vec)
> {
> - int i, n_slots, len;
> + int i, len;
> + size_t n_slots;
>
> /* Compute the size. We compute the size in number of slots to
> avoid issues with string padding. */
> @@ -386,28 +414,22 @@ write_exp_string_vector (int type, struct stoken_vector *vec)
> len = EXP_ELEM_TO_BYTES (n_slots) - 1;
>
> n_slots += 4;
> - if ((expout_ptr + n_slots) >= expout_size)
> - {
> - expout_size = max (expout_size * 2, expout_ptr + n_slots + 10);
> - expout = (struct expression *)
> - xrealloc ((char *) expout, (sizeof (struct expression)
> - + EXP_ELEM_TO_BYTES (expout_size)));
> - }
> + increase_expout_size (ps, n_slots);
>
> - write_exp_elt_opcode (OP_STRING);
> - write_exp_elt_longcst (len);
> - write_exp_elt_longcst (type);
> + write_exp_elt_opcode (ps, OP_STRING);
> + write_exp_elt_longcst (ps, len);
> + write_exp_elt_longcst (ps, type);
>
> for (i = 0; i < vec->len; ++i)
> {
> - write_exp_elt_longcst (vec->tokens[i].length);
> - memcpy (&expout->elts[expout_ptr], vec->tokens[i].ptr,
> + write_exp_elt_longcst (ps, vec->tokens[i].length);
> + memcpy (&ps->expout->elts[ps->expout_ptr], vec->tokens[i].ptr,
> vec->tokens[i].length);
> - expout_ptr += BYTES_TO_EXP_ELEM (vec->tokens[i].length);
> + ps->expout_ptr += BYTES_TO_EXP_ELEM (vec->tokens[i].length);
> }
>
> - write_exp_elt_longcst (len);
> - write_exp_elt_opcode (OP_STRING);
> + write_exp_elt_longcst (ps, len);
> + write_exp_elt_opcode (ps, OP_STRING);
> }
>
> /* Add a bitstring constant to the end of the expression.
> @@ -422,11 +444,11 @@ write_exp_string_vector (int type, struct stoken_vector *vec)
> either end of the bitstring. */
>
> void
> -write_exp_bitstring (struct stoken str)
> +write_exp_bitstring (struct parser_state *ps, struct stoken str)
> {
> int bits = str.length; /* length in bits */
> int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
> - int lenelt;
> + size_t lenelt;
> char *strdata;
>
> /* Compute the number of expression elements required to hold the bitstring,
> @@ -435,33 +457,24 @@ write_exp_bitstring (struct stoken str)
>
> lenelt = 2 + BYTES_TO_EXP_ELEM (len);
>
> - /* Ensure that we have enough available expression elements to store
> - everything. */
> -
> - if ((expout_ptr + lenelt) >= expout_size)
> - {
> - expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
> - expout = (struct expression *)
> - xrealloc ((char *) expout, (sizeof (struct expression)
> - + EXP_ELEM_TO_BYTES (expout_size)));
> - }
> + increase_expout_size (ps, lenelt);
>
> /* Write the leading length expression element (which advances the current
> expression element index), then write the bitstring constant, and then
> write the trailing length expression element. */
>
> - write_exp_elt_longcst ((LONGEST) bits);
> - strdata = (char *) &expout->elts[expout_ptr];
> + write_exp_elt_longcst (ps, (LONGEST) bits);
> + strdata = (char *) &ps->expout->elts[ps->expout_ptr];
> memcpy (strdata, str.ptr, len);
> - expout_ptr += lenelt - 2;
> - write_exp_elt_longcst ((LONGEST) bits);
> + ps->expout_ptr += lenelt - 2;
> + write_exp_elt_longcst (ps, (LONGEST) bits);
> }
>
> /* Add the appropriate elements for a minimal symbol to the end of
> the expression. */
>
> void
> -write_exp_msymbol (struct minimal_symbol *msymbol)
> +write_exp_msymbol (struct parser_state *ps, struct minimal_symbol *msymbol)
> {
> struct objfile *objfile = msymbol_objfile (msymbol);
> struct gdbarch *gdbarch = get_objfile_arch (objfile);
> @@ -499,60 +512,60 @@ write_exp_msymbol (struct minimal_symbol *msymbol)
> if (overlay_debugging)
> addr = symbol_overlayed_address (addr, section);
>
> - write_exp_elt_opcode (OP_LONG);
> + write_exp_elt_opcode (ps, OP_LONG);
> /* Let's make the type big enough to hold a 64-bit address. */
> - write_exp_elt_type (objfile_type (objfile)->builtin_core_addr);
> - write_exp_elt_longcst ((LONGEST) addr);
> - write_exp_elt_opcode (OP_LONG);
> + write_exp_elt_type (ps, objfile_type (objfile)->builtin_core_addr);
> + write_exp_elt_longcst (ps, (LONGEST) addr);
> + write_exp_elt_opcode (ps, OP_LONG);
>
> if (section && section->the_bfd_section->flags & SEC_THREAD_LOCAL)
> {
> - write_exp_elt_opcode (UNOP_MEMVAL_TLS);
> - write_exp_elt_objfile (objfile);
> - write_exp_elt_type (objfile_type (objfile)->nodebug_tls_symbol);
> - write_exp_elt_opcode (UNOP_MEMVAL_TLS);
> + write_exp_elt_opcode (ps, UNOP_MEMVAL_TLS);
> + write_exp_elt_objfile (ps, objfile);
> + write_exp_elt_type (ps, objfile_type (objfile)->nodebug_tls_symbol);
> + write_exp_elt_opcode (ps, UNOP_MEMVAL_TLS);
> return;
> }
>
> - write_exp_elt_opcode (UNOP_MEMVAL);
> + write_exp_elt_opcode (ps, UNOP_MEMVAL);
> switch (type)
> {
> case mst_text:
> case mst_file_text:
> case mst_solib_trampoline:
> - write_exp_elt_type (objfile_type (objfile)->nodebug_text_symbol);
> + write_exp_elt_type (ps, objfile_type (objfile)->nodebug_text_symbol);
> break;
>
> case mst_text_gnu_ifunc:
> - write_exp_elt_type (objfile_type (objfile)
> - ->nodebug_text_gnu_ifunc_symbol);
> + write_exp_elt_type (ps, objfile_type (objfile)
> + ->nodebug_text_gnu_ifunc_symbol);
> break;
>
> case mst_data:
> case mst_file_data:
> case mst_bss:
> case mst_file_bss:
> - write_exp_elt_type (objfile_type (objfile)->nodebug_data_symbol);
> + write_exp_elt_type (ps, objfile_type (objfile)->nodebug_data_symbol);
> break;
>
> case mst_slot_got_plt:
> - write_exp_elt_type (objfile_type (objfile)->nodebug_got_plt_symbol);
> + write_exp_elt_type (ps, objfile_type (objfile)->nodebug_got_plt_symbol);
> break;
>
> default:
> - write_exp_elt_type (objfile_type (objfile)->nodebug_unknown_symbol);
> + write_exp_elt_type (ps, objfile_type (objfile)->nodebug_unknown_symbol);
> break;
> }
> - write_exp_elt_opcode (UNOP_MEMVAL);
> + write_exp_elt_opcode (ps, UNOP_MEMVAL);
> }
>
> /* Mark the current index as the starting location of a structure
> expression. This is used when completing on field names. */
>
> void
> -mark_struct_expression (void)
> +mark_struct_expression (struct parser_state *ps)
> {
> - expout_last_struct = expout_ptr;
> + expout_last_struct = ps->expout_ptr;
> }
>
> \f
> @@ -578,7 +591,7 @@ mark_struct_expression (void)
> value in the value history, I.e. $$1 */
>
> void
> -write_dollar_variable (struct stoken str)
> +write_dollar_variable (struct parser_state *ps, struct stoken str)
> {
> struct symbol *sym = NULL;
> struct minimal_symbol *msym = NULL;
> @@ -616,7 +629,7 @@ write_dollar_variable (struct stoken str)
>
> /* Handle tokens that refer to machine registers:
> $ followed by a register name. */
> - i = user_reg_map_name_to_regnum (parse_gdbarch,
> + i = user_reg_map_name_to_regnum (parse_gdbarch (ps),
> str.ptr + 1, str.length - 1);
> if (i >= 0)
> goto handle_register;
> @@ -626,9 +639,9 @@ write_dollar_variable (struct stoken str)
> isym = lookup_only_internalvar (copy_name (str) + 1);
> if (isym)
> {
> - write_exp_elt_opcode (OP_INTERNALVAR);
> - write_exp_elt_intern (isym);
> - write_exp_elt_opcode (OP_INTERNALVAR);
> + write_exp_elt_opcode (ps, OP_INTERNALVAR);
> + write_exp_elt_intern (ps, isym);
> + write_exp_elt_opcode (ps, OP_INTERNALVAR);
> return;
> }
>
> @@ -639,36 +652,36 @@ write_dollar_variable (struct stoken str)
> VAR_DOMAIN, (int *) NULL);
> if (sym)
> {
> - write_exp_elt_opcode (OP_VAR_VALUE);
> - write_exp_elt_block (block_found); /* set by lookup_symbol */
> - write_exp_elt_sym (sym);
> - write_exp_elt_opcode (OP_VAR_VALUE);
> + write_exp_elt_opcode (ps, OP_VAR_VALUE);
> + write_exp_elt_block (ps, block_found); /* set by lookup_symbol */
> + write_exp_elt_sym (ps, sym);
> + write_exp_elt_opcode (ps, OP_VAR_VALUE);
> return;
> }
> msym = lookup_minimal_symbol (copy_name (str), NULL, NULL);
> if (msym)
> {
> - write_exp_msymbol (msym);
> + write_exp_msymbol (ps, msym);
> return;
> }
>
> /* Any other names are assumed to be debugger internal variables. */
>
> - write_exp_elt_opcode (OP_INTERNALVAR);
> - write_exp_elt_intern (create_internalvar (copy_name (str) + 1));
> - write_exp_elt_opcode (OP_INTERNALVAR);
> + write_exp_elt_opcode (ps, OP_INTERNALVAR);
> + write_exp_elt_intern (ps, create_internalvar (copy_name (str) + 1));
> + write_exp_elt_opcode (ps, OP_INTERNALVAR);
> return;
> handle_last:
> - write_exp_elt_opcode (OP_LAST);
> - write_exp_elt_longcst ((LONGEST) i);
> - write_exp_elt_opcode (OP_LAST);
> + write_exp_elt_opcode (ps, OP_LAST);
> + write_exp_elt_longcst (ps, (LONGEST) i);
> + write_exp_elt_opcode (ps, OP_LAST);
> return;
> handle_register:
> - write_exp_elt_opcode (OP_REGISTER);
> + write_exp_elt_opcode (ps, OP_REGISTER);
> str.length--;
> str.ptr++;
> - write_exp_string (str);
> - write_exp_elt_opcode (OP_REGISTER);
> + write_exp_string (ps, str);
> + write_exp_elt_opcode (ps, OP_REGISTER);
> return;
> }
>
> @@ -1093,6 +1106,7 @@ parse_exp_in_context (char **stringptr, struct block *block, int comma,
> volatile struct gdb_exception except;
> struct cleanup *old_chain;
> const struct language_defn *lang = NULL;
> + struct parser_state ps;
> int subexp;
>
> lexptr = *stringptr;
> @@ -1156,56 +1170,44 @@ parse_exp_in_context (char **stringptr, struct block *block, int comma,
> else
> lang = current_language;
>
> - expout_size = 10;
> - expout_ptr = 0;
> - expout = (struct expression *)
> - xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
> - expout->language_defn = lang;
> - expout->gdbarch = get_current_arch ();
> + initialize_expout (&ps, 10, lang, get_current_arch ());
>
> TRY_CATCH (except, RETURN_MASK_ALL)
> {
> - if (lang->la_parser ())
> - lang->la_error (NULL);
> + if (lang->la_parser (&ps))
> + lang->la_error (&ps, NULL);
> }
> if (except.reason < 0)
> {
> if (! in_parse_field)
> {
> - xfree (expout);
> + xfree (ps.expout);
> throw_exception (except);
> }
> }
>
> discard_cleanups (old_chain);
>
> - /* Record the actual number of expression elements, and then
> - reallocate the expression memory so that we free up any
> - excess elements. */
> -
> - expout->nelts = expout_ptr;
> - expout = (struct expression *)
> - xrealloc ((char *) expout,
> - sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_ptr));
> + reallocate_expout (&ps);
>
> /* Convert expression from postfix form as generated by yacc
> parser, to a prefix form. */
>
> if (expressiondebug)
> - dump_raw_expression (expout, gdb_stdlog,
> + dump_raw_expression (ps.expout, gdb_stdlog,
> "before conversion to prefix form");
>
> - subexp = prefixify_expression (expout);
> + subexp = prefixify_expression (ps.expout);
> if (out_subexp)
> *out_subexp = subexp;
>
> - lang->la_post_parser (&expout, void_context_p);
> + lang->la_post_parser (&ps.expout, void_context_p);
>
> if (expressiondebug)
> - dump_prefix_expression (expout, gdb_stdlog);
> + dump_prefix_expression (ps.expout, gdb_stdlog);
>
> *stringptr = lexptr;
> - return expout;
> + return ps.expout;
> }
>
> /* Parse STRING as an expression, and complain if this fails
> @@ -1372,9 +1374,9 @@ push_type_int (int n)
> }
>
> void
> -push_type_address_space (char *string)
> +push_type_address_space (struct parser_state *ps, char *string)
> {
> - push_type_int (address_space_name_to_int (parse_gdbarch, string));
> + push_type_int (address_space_name_to_int (parse_gdbarch (ps), string));
> }
>
> enum type_pieces
> @@ -1644,6 +1646,21 @@ exp_uses_objfile (struct expression *exp, struct objfile *objfile)
> return exp_iterate (exp, exp_uses_objfile_iter, objfile);
> }
>
> +/* See definition in parser-defs.h. */
> +
> +void
> +increase_expout_size (struct parser_state *ps, size_t lenelt)
> +{
> + if ((ps->expout_ptr + lenelt) >= ps->expout_size)
> + {
> + ps->expout_size = max (ps->expout_size * 2,
> + ps->expout_ptr + lenelt + 10);
> + ps->expout = (struct expression *)
> + xrealloc (ps->expout, (sizeof (struct expression)
> + + EXP_ELEM_TO_BYTES (ps->expout_size)));
> + }
> +}
> +
> void
> _initialize_parse (void)
> {
> diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
> index 16b40ac..89880cb 100644
> --- a/gdb/parser-defs.h
> +++ b/gdb/parser-defs.h
> @@ -30,12 +30,24 @@ struct block;
>
> extern int parser_debug;
>
> -extern struct expression *expout;
> -extern int expout_size;
> -extern int expout_ptr;
> +#define parse_gdbarch(ps) ((ps)->expout->gdbarch)
> +#define parse_language(ps) ((ps)->expout->language_defn)
>
> -#define parse_gdbarch (expout->gdbarch)
> -#define parse_language (expout->language_defn)
> +struct parser_state
> +{
> + /* The expression related to this parser state. */
> +
> + struct expression *expout;
> +
> + /* The size of the expression above. */
> +
> + size_t expout_size;
> +
> + /* The number of elements already in the expression. This is used
> + to know where to put new elements. */
> +
> + size_t expout_ptr;
> +};
>
> /* If this is nonzero, this block is used as the lexical context
> for symbol names. */
> @@ -130,35 +142,38 @@ union type_stack_elt
> extern union type_stack_elt *type_stack;
> extern int type_stack_depth, type_stack_size;
>
> -extern void write_exp_elt_opcode (enum exp_opcode);
> +extern void write_exp_elt_opcode (struct parser_state *, enum exp_opcode);
>
> -extern void write_exp_elt_sym (struct symbol *);
> +extern void write_exp_elt_sym (struct parser_state *, struct symbol *);
>
> -extern void write_exp_elt_longcst (LONGEST);
> +extern void write_exp_elt_longcst (struct parser_state *, LONGEST);
>
> -extern void write_exp_elt_dblcst (DOUBLEST);
> +extern void write_exp_elt_dblcst (struct parser_state *, DOUBLEST);
>
> -extern void write_exp_elt_decfloatcst (gdb_byte *);
> +extern void write_exp_elt_decfloatcst (struct parser_state *, gdb_byte *);
>
> -extern void write_exp_elt_type (struct type *);
> +extern void write_exp_elt_type (struct parser_state *, struct type *);
>
> -extern void write_exp_elt_intern (struct internalvar *);
> +extern void write_exp_elt_intern (struct parser_state *, struct internalvar *);
>
> -extern void write_exp_string (struct stoken);
> +extern void write_exp_string (struct parser_state *, struct stoken);
>
> -void write_exp_string_vector (int type, struct stoken_vector *vec);
> +void write_exp_string_vector (struct parser_state *, int type,
> + struct stoken_vector *vec);
>
> -extern void write_exp_bitstring (struct stoken);
> +extern void write_exp_bitstring (struct parser_state *, struct stoken);
>
> -extern void write_exp_elt_block (struct block *);
> +extern void write_exp_elt_block (struct parser_state *, struct block *);
>
> -extern void write_exp_elt_objfile (struct objfile *objfile);
> +extern void write_exp_elt_objfile (struct parser_state *,
> + struct objfile *objfile);
>
> -extern void write_exp_msymbol (struct minimal_symbol *);
> +extern void write_exp_msymbol (struct parser_state *,
> + struct minimal_symbol *);
>
> -extern void write_dollar_variable (struct stoken str);
> +extern void write_dollar_variable (struct parser_state *, struct stoken str);
>
> -extern void mark_struct_expression (void);
> +extern void mark_struct_expression (struct parser_state *);
>
> extern char *find_template_name_end (char *);
>
> @@ -172,7 +187,7 @@ extern void push_type (enum type_pieces);
>
> extern void push_type_int (int);
>
> -extern void push_type_address_space (char *);
> +extern void push_type_address_space (struct parser_state *, char *);
>
> extern enum type_pieces pop_type (void);
>
> @@ -315,4 +330,10 @@ extern void parser_fprintf (FILE *, const char *, ...) ATTRIBUTE_PRINTF (2, 3);
>
> extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
>
> +/* Reallocate the `expout' pointer inside PS so that it can accommodate
> + at least LENELT expression elements. This function does nothing if
> + there is enough room for the elements. */
> +
> +extern void increase_expout_size (struct parser_state *ps, size_t lenelt);
> +
> #endif /* PARSER_DEFS_H */
>
>