From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21967 invoked by alias); 15 Jan 2012 21:17:57 -0000 Received: (qmail 21956 invoked by uid 22791); 15 Jan 2012 21:17:54 -0000 X-SWARE-Spam-Status: No, hits=-6.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,TW_CP,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 15 Jan 2012 21:17:37 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q0FLHbNt025556 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sun, 15 Jan 2012 16:17:37 -0500 Received: from host2.jankratochvil.net (ovpn-116-21.ams2.redhat.com [10.36.116.21]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q0FLHQ1B027261 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Sun, 15 Jan 2012 16:17:28 -0500 Date: Sun, 15 Jan 2012 22:03:00 -0000 From: Jan Kratochvil To: Sergio Durigan Junior Cc: gdb-patches@sourceware.org Subject: Re: [RFC 1/8] Language independent bits Message-ID: <20120115211725.GA4330@host2.jankratochvil.net> References: <20120115203420.GA18901@host2.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-01/txt/msg00537.txt.bz2 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 = > }; > > /* 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) > } > } > > + > +/* 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; > } > > > @@ -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 */ > >