Re: [RFC 1/8] Language independent bits

Sergio Durigan Junior
2012-01-15T21:08:01Z

On Sunday, January 15 2012, Jan Kratochvil wrote:

> On Sun, 15 Jan 2012 19:55:27 +0100, Sergio Durigan Junior wrote:
>> 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"));
>> }
>
> Do you use `ps' in these two functions in some later patch? Otherwise I do
> not think it should be passed. It can be always passed (sure incl. updating
> callers and the callers of the callers) later when needed.

By "these two functions" you mean on `unk_lang_error' and
`unk_lang_parser'? If so, then the answer is "no", but I still need to
pass `ps' because of the prototype of `la_parser' and `la_error'.

But if you mean `la_parser' and `la_error', then the answer is that `ps'
is used inside `la_parser', but not used inside `la_error'. However, by
Bison rules, if you change the `yyparse' header you should reflect the
changes to `yyerror' header.

>> +static void
>> +initialize_expout (struct parser_state *ps, int initial_size,
>> + const struct language_defn *lang,
>> + struct gdbarch *gdbarch)
>> +{
>> + ps->expout_size = initial_size;
>> + ps->expout_ptr = 0;
>> + 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. If you mean I should
remove the cast to `struct expression *', then OK, I can do that.

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 */