This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v3 01/10] Language independent bits
- From: Sergio Durigan Junior <sergiodj at redhat dot com>
- To: GDB Patches <gdb-patches at sourceware dot org>
- Cc: Tom Tromey <tromey at redhat dot com>, Sergio Durigan Junior <sergiodj at redhat dot com>
- Date: Sat, 25 Jan 2014 03:57:38 -0200
- Subject: [PATCH v3 01/10] Language independent bits
- Authentication-results: sourceware.org; auth=none
- References: <1390629467-27139-1-git-send-email-sergiodj at redhat dot com>
This patch does a refactoring on gdb/{parse.c,parser-defs.h,language.*}
in order to remove the `expout*' globals. It creates a new
structure called `parser_state' which holds those variables per-parser,
and eventually will hold all the global parser variables.
This patch also creates a helper cleanup responsible for resetting the
value of the parser state on each parser.
2014-01-25 Sergio Durigan Junior <sergiodj@redhat.com>
* language.c (unk_lang_parser): Add "struct parser_state"
argument.
* language.h (struct language_defn) <la_parser>: Likewise.
* parse.c (expout, expout_size, expout_ptr): Remove variables.
(initialize_expout): Add "struct parser_state" argument.
Rewrite function to use the parser state.
(reallocate_expout, write_exp_elt, write_exp_elt_opcode,
write_exp_elt_sym, write_exp_elt_block, write_exp_elt_objfile,
write_exp_elt_longcst, write_exp_elt_dblcst,
write_exp_elt_decfloatcst, write_exp_elt_type,
write_exp_elt_intern, write_exp_string, write_exp_string_vector,
write_exp_bitstring, write_exp_msymbol, mark_struct_expression,
write_dollar_variable): Likewise.
(parse_exp_in_context_1): Use parser state.
(insert_type_address_space): Add "struct parser_state" argument.
Use parser state.
(increase_expout_size): New function.
* parser-defs.h: Forward declare "struct language_defn" and
"struct parser_state".
(expout, expout_size, expout_ptr): Remove extern declarations.
(parse_gdbarch, parse_language): Rewrite macro declarations to
accept the parser state.
(struct parser_state): New struct.
(initialize_expout, reallocate_expout, write_exp_elt_opcode,
write_exp_elt_sym, write_exp_elt_longcst, write_exp_elt_dblcst,
write_exp_elt_decfloatcst, write_exp_elt_type,
write_exp_elt_intern, write_exp_string, write_exp_string_vector,
write_exp_bitstring, write_exp_elt_block, write_exp_elt_objfile,
write_exp_msymbol, write_dollar_variable,
mark_struct_expression, insert_type_address_space): Add "struct
parser_state" argument.
(increase_expout_size): New function.
* utils.c (do_clear_parser_state): New function.
(make_cleanup_clear_parser_state): Likewise.
* utils.h (make_cleanup_clear_parser_state): New function
prototype.
---
gdb/language.c | 4 +-
gdb/language.h | 3 +-
gdb/parse.c | 277 +++++++++++++++++++++++++++---------------------------
gdb/parser-defs.h | 83 ++++++++++------
gdb/utils.c | 18 ++++
gdb/utils.h | 4 +
6 files changed, 217 insertions(+), 172 deletions(-)
diff --git a/gdb/language.c b/gdb/language.c
index ae0fa15..d5502f2 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -50,7 +50,7 @@ extern void _initialize_language (void);
static void unk_lang_error (char *);
-static int unk_lang_parser (void);
+static int unk_lang_parser (struct parser_state *);
static void show_check (char *, int);
@@ -694,7 +694,7 @@ 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;
}
diff --git a/gdb/language.h b/gdb/language.h
index ded595f..9e95bf2 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -34,6 +34,7 @@ struct ui_file;
struct value_print_options;
struct type_print_options;
struct lang_varobj_ops;
+struct parser_state;
#define MAX_FORTRAN_DIMS 7 /* Maximum number of F77 array dims. */
@@ -164,7 +165,7 @@ struct language_defn
/* Parser function. */
- int (*la_parser) (void);
+ int (*la_parser) (struct parser_state *);
/* Parser error function. */
diff --git a/gdb/parse.c b/gdb/parse.c
index 1171289..d6e1a01 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -67,9 +67,6 @@ const struct exp_descriptor exp_descriptor_standard =
};
/* Global variables declared in parser-defs.h (and commented there). */
-struct expression *expout;
-int expout_size;
-int expout_ptr;
const struct block *expression_context_block;
CORE_ADDR expression_context_pc;
const struct block *innermost_block;
@@ -185,118 +182,121 @@ free_funcalls (void *ignore)
}
}
-/* This page contains the functions for adding data to the struct expression
- being constructed. */
/* See definition in parser-defs.h. */
void
-initialize_expout (int initial_size, const struct language_defn *lang,
+initialize_expout (struct parser_state *ps, size_t initial_size,
+ const struct language_defn *lang,
struct gdbarch *gdbarch)
{
- expout_size = initial_size;
- expout_ptr = 0;
- expout = xmalloc (sizeof (struct expression)
- + EXP_ELEM_TO_BYTES (expout_size));
- expout->language_defn = lang;
- expout->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;
}
/* See definition in parser-defs.h. */
void
-reallocate_expout (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. */
- expout->nelts = expout_ptr;
- expout = xrealloc ((char *) expout,
- sizeof (struct expression)
- + EXP_ELEM_TO_BYTES (expout_ptr));
+ 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. */
+
/* Add one element to the end of the expression. */
/* To avoid a bug in the Sun 4 compiler, we pass things that can fit into
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 (const struct block *b)
+write_exp_elt_block (struct parser_state *ps, const 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;
@@ -304,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.
@@ -349,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
@@ -362,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.
@@ -400,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. */
@@ -421,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.
@@ -457,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,
@@ -470,33 +457,25 @@ 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 bound_minimal_symbol bound_msym)
+write_exp_msymbol (struct parser_state *ps,
+ struct bound_minimal_symbol bound_msym)
{
struct minimal_symbol *msymbol = bound_msym.minsym;
struct objfile *objfile = bound_msym.objfile;
@@ -536,62 +515,62 @@ write_exp_msymbol (struct bound_minimal_symbol bound_msym)
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)
{
gdb_assert (parse_completion
&& expout_tag_completion_type == TYPE_CODE_UNDEF);
- expout_last_struct = expout_ptr;
+ expout_last_struct = ps->expout_ptr;
}
/* Indicate that the current parser invocation is completing a tag.
@@ -638,7 +617,7 @@ mark_completion_tag (enum type_code tag, const char *ptr, int length)
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 bound_minimal_symbol msym;
@@ -676,7 +655,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;
@@ -686,9 +665,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;
}
@@ -699,36 +678,36 @@ write_dollar_variable (struct stoken str)
VAR_DOMAIN, 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_bound_minimal_symbol (copy_name (str));
if (msym.minsym)
{
- 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;
}
@@ -1161,6 +1140,7 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
volatile struct gdb_exception except;
struct cleanup *old_chain, *inner_chain;
const struct language_defn *lang = NULL;
+ struct parser_state ps;
int subexp;
lexptr = *stringptr;
@@ -1233,47 +1213,48 @@ parse_exp_in_context_1 (const char **stringptr, CORE_ADDR pc,
While we need CURRENT_LANGUAGE to be set to LANG (for lookup_symbol
and others called from *.y) ensure CURRENT_LANGUAGE gets restored
to the value matching SELECTED_FRAME as set by get_current_arch. */
- initialize_expout (10, lang, get_current_arch ());
+
+ initialize_expout (&ps, 10, lang, get_current_arch ());
inner_chain = make_cleanup_restore_current_language ();
set_language (lang->la_language);
TRY_CATCH (except, RETURN_MASK_ALL)
{
- if (lang->la_parser ())
+ if (lang->la_parser (&ps))
lang->la_error (NULL);
}
if (except.reason < 0)
{
if (! parse_completion)
{
- xfree (expout);
+ xfree (ps.expout);
throw_exception (except);
}
}
- reallocate_expout ();
+ 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);
do_cleanups (inner_chain);
discard_cleanups (old_chain);
*stringptr = lexptr;
- return expout;
+ return ps.expout;
}
/* Parse STRING as an expression, and complain if this fails
@@ -1512,7 +1493,7 @@ push_type_int (int n)
item. */
void
-insert_type_address_space (char *string)
+insert_type_address_space (struct parser_state *pstate, char *string)
{
union type_stack_elt element;
int slot;
@@ -1527,7 +1508,8 @@ insert_type_address_space (char *string)
element.piece = tp_space_identifier;
insert_into_type_stack (slot, element);
- element.int_val = address_space_name_to_int (parse_gdbarch, string);
+ element.int_val = address_space_name_to_int (parse_gdbarch (pstate),
+ string);
insert_into_type_stack (slot, element);
}
@@ -1909,6 +1891,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 c3f2607..97c53b9 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -28,15 +28,29 @@
#include "expression.h"
struct block;
+struct language_defn;
+struct internalvar;
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. */
@@ -148,19 +162,21 @@ struct type_stack
};
/* Helper function to initialize the expout, expout_size, expout_ptr
- trio before it is used to store expression elements created during
- the parsing of an expression. INITIAL_SIZE is the initial size of
+ 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 (int, const struct language_defn *,
- struct gdbarch *);
+extern void initialize_expout (struct parser_state *ps,
+ size_t initial_size,
+ const struct language_defn *lang,
+ struct gdbarch *gdbarch);
-/* Helper function that frees any unsed space in the expout array.
- It is generally used when the parser has just been parsed and
- created. */
+/* 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 (void);
+extern void reallocate_expout (struct parser_state *ps);
/* Reverse an expression from suffix form (in which it is constructed)
to prefix form (in which we can conveniently print or execute it).
@@ -171,35 +187,38 @@ extern void reallocate_expout (void);
extern int prefixify_expression (struct expression *expr);
-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 (const struct block *);
+extern void write_exp_elt_block (struct parser_state *, const 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 bound_minimal_symbol);
+extern void write_exp_msymbol (struct parser_state *,
+ struct bound_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 const char *find_template_name_end (const char *);
@@ -215,7 +234,7 @@ extern void push_type (enum type_pieces);
extern void push_type_int (int);
-extern void insert_type_address_space (char *);
+extern void insert_type_address_space (struct parser_state *, char *);
extern enum type_pieces pop_type (void);
@@ -375,5 +394,11 @@ extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
extern void mark_completion_tag (enum type_code, const char *ptr,
int length);
+/* 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 */
diff --git a/gdb/utils.c b/gdb/utils.c
index e062e89..b2f4305 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -507,6 +507,24 @@ make_cleanup_restore_current_language (void)
(void *) (uintptr_t) saved_lang);
}
+/* Helper function for make_cleanup_clear_parser_state. */
+
+static void
+do_clear_parser_state (void *ptr)
+{
+ struct parser_state **p = (struct parser_state **) ptr;
+
+ *p = NULL;
+}
+
+/* Clean (i.e., set to NULL) the parser state variable P. */
+
+struct cleanup *
+make_cleanup_clear_parser_state (struct parser_state **p)
+{
+ return make_cleanup (do_clear_parser_state, (void *) p);
+}
+
/* This function is useful for cleanups.
Do
diff --git a/gdb/utils.h b/gdb/utils.h
index 8bbcc5f..9c1ae70 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -114,6 +114,10 @@ extern struct cleanup *make_cleanup_restore_current_language (void);
extern struct cleanup *make_cleanup_htab_delete (htab_t htab);
+struct parser_state;
+extern struct cleanup *make_cleanup_clear_parser_state
+ (struct parser_state **p);
+
extern void free_current_contents (void *);
extern void init_page_info (void);
--
1.7.11.7