From patchwork Sat Mar 22 04:43:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergio Durigan Junior X-Patchwork-Id: 224 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx20.g.dreamhost.com (caibbdcaaahc.dreamhost.com [208.113.200.72]) by wilcox.dreamhost.com (Postfix) with ESMTP id 2A8213600C2 for ; Fri, 21 Mar 2014 21:44:32 -0700 (PDT) Received: by homiemail-mx20.g.dreamhost.com (Postfix, from userid 14314964) id D1528409C6413; Fri, 21 Mar 2014 21:44:31 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx20.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx20.g.dreamhost.com (Postfix) with ESMTPS id AADBE40978ABB for ; Fri, 21 Mar 2014 21:44:31 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=VTZt+KZqz3MuGVmDTBNSz8cqqACPc9Y m6oedRV4W4gc6CII/O3Pdb5wxK9/cYWaHMPmgsTPcKOdSxsrjdkpyxWAJ5yeq9PO MXdSK75mK6wMULg1uNfFrhClf+/tJAnqCqwPlRQUqcaopzjPOvwvJeQOCyHiwoAI S4HkLFVEz0DU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; s=default; bh=wfZf4mwSbCS4zSJQd3yBAVGnB10=; b=uuVqu UbF55wb/yO9AmzRniAnHIhmkLkB1jHYIUeJWOqxlx2iT6Y51YfxeFIdJ0004aMtc 0pEZ56DIcKZo2iN+uiUOX0vmXiRslbiPDIm8r1MwU+Le8aw7XZ7E8bOKEVhtCCBf DAeNhFiIkB4yH+bvZ+GYxlEqVs6zaXO4jWdT74= Received: (qmail 30407 invoked by alias); 22 Mar 2014 04:44:19 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 30298 invoked by uid 89); 22 Mar 2014 04:44:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 22 Mar 2014 04:44:13 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s2M4iCaT023546 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sat, 22 Mar 2014 00:44:12 -0400 Received: from psique.redhat.com (ovpn-113-73.phx2.redhat.com [10.3.113.73]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s2M4i8XC001988; Sat, 22 Mar 2014 00:44:10 -0400 From: Sergio Durigan Junior To: GDB Patches Cc: Tom Tromey , Sergio Durigan Junior Subject: [PATCH v4 01/10] Language independent bits Date: Sat, 22 Mar 2014 01:43:43 -0300 Message-Id: <1395463432-29750-2-git-send-email-sergiodj@redhat.com> In-Reply-To: <1395463432-29750-1-git-send-email-sergiodj@redhat.com> References: <1395463432-29750-1-git-send-email-sergiodj@redhat.com> X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in 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-03-22 Sergio Durigan Junior * language.c (unk_lang_parser): Add "struct parser_state" argument. * language.h (struct language_defn) : 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 c6e25a9..b0da2ef 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 364470c..a8a7cb3 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -466,6 +466,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 d6df2ee..33371ac 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -115,6 +115,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);