From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29566 invoked by alias); 17 Dec 2007 06:42:35 -0000 Received: (qmail 29549 invoked by uid 22791); 17 Dec 2007 06:42:31 -0000 X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 17 Dec 2007 06:42:25 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 4E1D12A9637; Mon, 17 Dec 2007 01:42:23 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id K-3bk8Pf+NnK; Mon, 17 Dec 2007 01:42:23 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 8002C2A9636; Mon, 17 Dec 2007 01:42:20 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id 50807E7ACA; Mon, 17 Dec 2007 07:42:13 +0100 (CET) Date: Mon, 17 Dec 2007 07:03:00 -0000 From: Joel Brobecker To: uweigand@de.ibm.com, gdb-patches@sourceware.org Subject: [RFC/RFA] Introduce new struct parse_context Message-ID: <20071217064213.GC9022@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="WIyZ46R2i8wDzkSu" Content-Disposition: inline User-Agent: Mutt/1.4.2.2i 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: 2007-12/txt/msg00256.txt.bz2 --WIyZ46R2i8wDzkSu Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 3319 all, I would like to introduce a new structure called "struct parse_context" which, for now, would contain the language and radix to use when doing some parsing. This is something that we already discussed in a more general way. This patch introduces: - struct parse_context - A function called "build_parse_context" that builds a parse_context structure from a language and radix. Eventually, when the struct grows, we will add more parameters to that function. - A macro: current_parse_context which returns a parse context using the current_language and the input_radix. This is the context that we should be using when parsing from a function that is a "command" (that is a function that implements a command) - A macro: wrong_parse_context, which is an alias to current_parse_context. This macro is useful to help breaking this task into incremental changes and is temporary, as the FIXME explains. I am using this macro when I am in a context where I don't have the parse_context to be used (yet), to make sure that I don't forget to fix it later. Will be removed when the task is complete. 2007-12-17 Joel Brobecker * expression.h (parse_context): New struct. (build_parse_context): Add declaration. (current_parse_context, wrong_parse_context): New macros. * parse.c (build_parse_context): New function. Tested on x86-linux. Depending on this patch is the following one, which introduces the use of that structure in the parse routines. I am putting that second patch with the first one in order to show how all this is going to be used. 2007-12-17 Joel Brobecker * expression.h (parse_expression): Add parse_context parameter. (parse_expression_in_context, parse_exp_1): Likewise. * parse.c (parse_exp_1): Add new parameter parse_context and use it. (parse_exp_in_context, parse_expression, parse_expression_in_context): Likewise. * ada-lang.c: Update calls to parse_expression and parse_exp_1. * objc-lang.c: Likewise. * breakpoint.c: Likewise. * value.c: Likewise. * ax-gdb.c: Likewise. * tracepoint.c: Likewise. * wrapper.c: Likewise. * eval.c: Likewise. * varobj.c: Likewise. * printcmd.c: Likewise. * cli/cli-script.c: Likewise. * mi/mi-main.c: Likewise. * typeprint.c (whatis_exp): Add new parameter parse_context. Update call to parse_expression. (whatis_command, ptype_command): Update call to whatis_exp. (maintenance_print_type): Update call to parse_expression. Also tested on x86-linux. I would like to commit these two patches now, and work progressively directly in the HEAD branch. All the changes that I am making should either not change the behavior, or make it better. Working on HEAD directly allows me to work progressively as time permits - I can always find 10-15 mins to work on one "wrong_parse_context" everyday. Finding a couple of hours is not always that easy. Also, I think that people will be able to follow the changes a little more easily rather than being bombarded by a truckload of patches. Would it be OK if I worked directly on HEAD? Thanks, -- Joel --WIyZ46R2i8wDzkSu Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="parse_context.diff" Content-length: 2306 Index: expression.h =================================================================== --- expression.h (revision 2) +++ expression.h (revision 3) @@ -387,6 +387,37 @@ struct expression /* From parse.c */ +/* Parsing an expression is dependent on a certain context such as + the language to use, or the input radix for numbers. This structure + contains that context information. */ + +struct parse_context + { + /* The language to use when parsing an expression. */ + const struct language_defn *language; + + /* The radix to use by default when parsing numbers. */ + int radix; + }; + +extern struct parse_context + build_parse_context (const struct language_defn *language, int radix); + +#define current_parse_context \ + (build_parse_context (current_language, input_radix)) + +/* FIXME: brobecker/2007-12-09: We are currently introducing the addition + of a struct parse_context parameter to all the parsing routines. + The addition of this parameter means that we need to update all + the callers, which often means that the caller should also be added + a struct parse_context parameter, which in turn often means that + the caller's caller should also be updated, etc etc etc. Rather than + updating the entire calling chains all at once, which would be a very + large change, we break the transition into smaller changes, with the use + of the following macro, which is a temporary use of current_parse_context. + This macro should be deleted once the transition is complete. */ +#define wrong_parse_context (current_parse_context) + extern struct expression *parse_expression (char *); extern struct expression *parse_expression_in_context (char *, int); Index: parse.c =================================================================== --- parse.c (revision 2) +++ parse.c (revision 3) @@ -911,6 +911,21 @@ prefixify_subexp (struct expression *ine outbeg += oplen; } } + +/* Return a parse_context structure using the given LANGUAGE + and RADIX. */ + +struct parse_context +build_parse_context (const struct language_defn *language, int radix) +{ + struct parse_context result; + + result.language = language; + result.radix = radix; + + return result; +} + /* This page contains the two entry points to this file. */ --WIyZ46R2i8wDzkSu Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="param_parse.diff" Content-length: 18780 Index: ada-lang.c =================================================================== --- ada-lang.c (revision 6) +++ ada-lang.c (revision 7) @@ -9675,7 +9675,8 @@ static struct expression * ada_parse_catchpoint_condition (char *cond_string, struct symtab_and_line sal) { - return (parse_exp_1 (&cond_string, block_for_pc (sal.pc), 0)); + return (parse_exp_1 (&cond_string, block_for_pc (sal.pc), 0, + wrong_parse_context)); } /* Return the symtab_and_line that should be used to insert an exception Index: objc-lang.c =================================================================== --- objc-lang.c (revision 6) +++ objc-lang.c (revision 7) @@ -1371,7 +1371,7 @@ print_object_command (char *args, int fr "The 'print-object' command requires an argument (an Objective-C object)"); { - struct expression *expr = parse_expression (args); + struct expression *expr = parse_expression (args, current_parse_context); struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); int pc = 0; Index: breakpoint.c =================================================================== --- breakpoint.c (revision 6) +++ breakpoint.c (revision 7) @@ -596,7 +596,13 @@ condition_command (char *arg, int from_t for (loc = b->loc; loc; loc = loc->next) { arg = p; - loc->cond = parse_exp_1 (&arg, block_for_pc (loc->address), 0); + /* FIXME: brobecker/2007-12-09: The current breakpoint + structures are defined in a way that assumes that the + parse_context used to express the condition is the same + as the parse_context of the condition. So use the + breakpoint parse_context to parse the condition. */ + loc->cond = parse_exp_1 (&arg, block_for_pc (loc->address), 0, + wrong_parse_context); if (*arg) error (_("Junk at end of expression")); } @@ -5126,7 +5132,8 @@ create_breakpoint (struct symtabs_and_li if (b->cond_string) { char *arg = b->cond_string; - loc->cond = parse_exp_1 (&arg, block_for_pc (loc->address), 0); + loc->cond = parse_exp_1 (&arg, block_for_pc (loc->address), 0, + wrong_parse_context); if (*arg) error (_("Garbage %s follows condition"), arg); } @@ -5421,7 +5428,7 @@ find_condition_and_thread (char *tok, CO if (toklen >= 1 && strncmp (tok, "if", toklen) == 0) { tok = cond_start = end_tok + 1; - parse_exp_1 (&tok, block_for_pc (pc), 0); + parse_exp_1 (&tok, block_for_pc (pc), 0, wrong_parse_context); cond_end = tok; *cond_string = savestring (cond_start, cond_end - cond_start); @@ -5900,7 +5907,7 @@ watch_command_1 (char *arg, int accessfl /* Parse arguments. */ innermost_block = NULL; exp_start = arg; - exp = parse_exp_1 (&arg, 0, 0); + exp = parse_exp_1 (&arg, 0, 0, current_parse_context); exp_end = arg; exp_valid_block = innermost_block; mark = value_mark (); @@ -5921,7 +5928,7 @@ watch_command_1 (char *arg, int accessfl if (toklen >= 1 && strncmp (tok, "if", toklen) == 0) { tok = cond_start = end_tok + 1; - cond = parse_exp_1 (&tok, 0, 0); + cond = parse_exp_1 (&tok, 0, 0, current_parse_context); cond_end = tok; } if (*tok) @@ -7381,7 +7388,7 @@ update_breakpoint_locations (struct brea TRY_CATCH (e, RETURN_MASK_ERROR) { new_loc->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), - 0); + 0, wrong_parse_context); } if (e.reason < 0) { @@ -7552,7 +7559,7 @@ breakpoint_re_set_one (void *bint) parse_expression. */ b->exp = NULL; } - b->exp = parse_expression (b->exp_string); + b->exp = parse_expression (b->exp_string, wrong_parse_context); b->exp_valid_block = innermost_block; mark = value_mark (); if (b->val) @@ -7577,7 +7584,8 @@ breakpoint_re_set_one (void *bint) to parse_exp_1. */ b->loc->cond = NULL; } - b->loc->cond = parse_exp_1 (&s, (struct block *) 0, 0); + b->loc->cond = parse_exp_1 (&s, (struct block *) 0, 0, + wrong_parse_context); } if (breakpoint_enabled (b)) mention (b); Index: value.c =================================================================== --- value.c (revision 6) +++ value.c (revision 7) @@ -714,7 +714,7 @@ init_if_undefined_command (char* args, i struct internalvar* intvar; /* Parse the expression - this is taken from set_command(). */ - struct expression *expr = parse_expression (args); + struct expression *expr = parse_expression (args, current_parse_context); register struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); Index: ax-gdb.c =================================================================== --- ax-gdb.c (revision 6) +++ ax-gdb.c (revision 7) @@ -1786,7 +1786,7 @@ agent_command (char *exp, int from_tty) if (exp == 0) error_no_arg (_("expression to translate")); - expr = parse_expression (exp); + expr = parse_expression (exp, current_parse_context); old_chain = make_cleanup (free_current_contents, &expr); agent = gen_trace_for_expr (get_frame_pc (fi), expr); make_cleanup_free_agent_expr (agent); Index: tracepoint.c =================================================================== --- tracepoint.c (revision 6) +++ tracepoint.c (revision 7) @@ -970,7 +970,9 @@ validate_actionline (char **line, struct } /* else fall thru, treat p as an expression and parse it! */ } - exp = parse_exp_1 (&p, block_for_pc (t->address), 1); + exp = parse_exp_1 (&p, block_for_pc (t->address), 1, + build_parse_context (language_def (t->language), + t->input_radix)); old_chain = make_cleanup (free_current_contents, &exp); if (exp->elts[0].opcode == OP_VAR_VALUE) @@ -1598,7 +1600,10 @@ encode_actions (struct tracepoint *t, ch struct agent_reqs areqs; exp = parse_exp_1 (&action_exp, - block_for_pc (t->address), 1); + block_for_pc (t->address), 1, + build_parse_context + (language_def (t->language), + t->input_radix)); old_chain = make_cleanup (free_current_contents, &exp); switch (exp->elts[0].opcode) Index: wrapper.c =================================================================== --- wrapper.c (revision 6) +++ wrapper.c (revision 7) @@ -29,7 +29,7 @@ gdb_parse_exp_1 (char **stringptr, struc TRY_CATCH (except, RETURN_MASK_ERROR) { - *expression = parse_exp_1 (stringptr, block, comma); + *expression = parse_exp_1 (stringptr, block, comma, wrong_parse_context); } if (except.reason < 0) Index: eval.c =================================================================== --- eval.c (revision 6) +++ eval.c (revision 7) @@ -82,7 +82,7 @@ evaluate_subexp (struct type *expect_typ CORE_ADDR parse_and_eval_address (char *exp) { - struct expression *expr = parse_expression (exp); + struct expression *expr = parse_expression (exp, wrong_parse_context); CORE_ADDR addr; struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); @@ -98,7 +98,8 @@ parse_and_eval_address (char *exp) CORE_ADDR parse_and_eval_address_1 (char **expptr) { - struct expression *expr = parse_exp_1 (expptr, (struct block *) 0, 0); + struct expression *expr = parse_exp_1 (expptr, (struct block *) 0, 0, + wrong_parse_context); CORE_ADDR addr; struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); @@ -113,7 +114,7 @@ parse_and_eval_address_1 (char **expptr) LONGEST parse_and_eval_long (char *exp) { - struct expression *expr = parse_expression (exp); + struct expression *expr = parse_expression (exp, wrong_parse_context); LONGEST retval; struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); @@ -126,7 +127,7 @@ parse_and_eval_long (char *exp) struct value * parse_and_eval (char *exp) { - struct expression *expr = parse_expression (exp); + struct expression *expr = parse_expression (exp, wrong_parse_context); struct value *val; struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); @@ -143,7 +144,8 @@ parse_and_eval (char *exp) struct value * parse_to_comma_and_eval (char **expp) { - struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1); + struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1, + wrong_parse_context); struct value *val; struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); @@ -2297,7 +2299,7 @@ parse_and_eval_type (char *p, int length tmp[length + 1] = ')'; tmp[length + 2] = '0'; tmp[length + 3] = '\0'; - expr = parse_expression (tmp); + expr = parse_expression (tmp, wrong_parse_context); if (expr->elts[0].opcode != UNOP_CAST) error (_("Internal error in eval_type.")); return expr->elts[1].type; Index: typeprint.c =================================================================== --- typeprint.c (revision 6) +++ typeprint.c (revision 7) @@ -45,7 +45,7 @@ static void ptype_command (char *, int); static void whatis_command (char *, int); -static void whatis_exp (char *, int); +static void whatis_exp (char *, int, struct parse_context parse_context); /* Print a description of a type in the format of a typedef for the current language. @@ -109,7 +109,7 @@ type_print (struct type *type, char *var show is passed to type_print. */ static void -whatis_exp (char *exp, int show) +whatis_exp (char *exp, int show, struct parse_context parse_context) { struct expression *expr; struct value *val; @@ -122,7 +122,7 @@ whatis_exp (char *exp, int show) if (exp) { - expr = parse_expression (exp); + expr = parse_expression (exp, parse_context); old_chain = make_cleanup (free_current_contents, &expr); val = evaluate_type (expr); } @@ -175,7 +175,7 @@ whatis_command (char *exp, int from_tty) /* Most of the time users do not want to see all the fields in a structure. If they do they can use the "ptype" command. Hence the "-1" below. */ - whatis_exp (exp, -1); + whatis_exp (exp, -1, current_parse_context); } /* TYPENAME is either the name of a type, or an expression. */ @@ -183,7 +183,7 @@ whatis_command (char *exp, int from_tty) static void ptype_command (char *typename, int from_tty) { - whatis_exp (typename, 1); + whatis_exp (typename, 1, current_parse_context); } /* Print integral scalar data VAL, of type TYPE, onto stdio stream STREAM. @@ -283,7 +283,7 @@ maintenance_print_type (char *typename, if (typename != NULL) { - expr = parse_expression (typename); + expr = parse_expression (typename, current_parse_context); old_chain = make_cleanup (free_current_contents, &expr); if (expr->elts[0].opcode == OP_TYPE) { Index: parse.c =================================================================== --- parse.c (revision 6) +++ parse.c (revision 7) @@ -105,7 +105,7 @@ static void prefixify_subexp (struct exp int); static struct expression *parse_exp_in_context (char **, struct block *, int, - int); + int, struct parse_context); void _initialize_parse (void); @@ -940,9 +940,10 @@ build_parse_context (const struct langua If COMMA is nonzero, stop if a comma is reached. */ struct expression * -parse_exp_1 (char **stringptr, struct block *block, int comma) +parse_exp_1 (char **stringptr, struct block *block, int comma, + struct parse_context parse_context) { - return parse_exp_in_context (stringptr, block, comma, 0); + return parse_exp_in_context (stringptr, block, comma, 0, parse_context); } /* As for parse_exp_1, except that if VOID_CONTEXT_P, then @@ -950,7 +951,7 @@ parse_exp_1 (char **stringptr, struct bl static struct expression * parse_exp_in_context (char **stringptr, struct block *block, int comma, - int void_context_p) + int void_context_p, struct parse_context parse_context) { struct cleanup *old_chain; @@ -994,11 +995,11 @@ parse_exp_in_context (char **stringptr, expout_ptr = 0; expout = (struct expression *) xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size)); - expout->language_defn = current_language; + expout->language_defn = parse_context.language; make_cleanup (free_current_contents, &expout); - if (current_language->la_parser ()) - current_language->la_error (NULL); + if (parse_context.language->la_parser ()) + parse_context.language->la_error (NULL); discard_cleanups (old_chain); @@ -1020,7 +1021,7 @@ parse_exp_in_context (char **stringptr, prefixify_expression (expout); - current_language->la_post_parser (&expout, void_context_p); + parse_context.language->la_post_parser (&expout, void_context_p); if (expressiondebug) dump_prefix_expression (expout, gdb_stdlog); @@ -1033,10 +1034,10 @@ parse_exp_in_context (char **stringptr, to use up all of the contents of STRING. */ struct expression * -parse_expression (char *string) +parse_expression (char *string, struct parse_context parse_context) { struct expression *exp; - exp = parse_exp_1 (&string, 0, 0); + exp = parse_exp_1 (&string, 0, 0, parse_context); if (*string) error (_("Junk after end of expression.")); return exp; @@ -1047,10 +1048,11 @@ parse_expression (char *string) no value is expected from the expression. */ struct expression * -parse_expression_in_context (char *string, int void_context_p) +parse_expression_in_context (char *string, int void_context_p, + struct parse_context parse_context) { struct expression *exp; - exp = parse_exp_in_context (&string, 0, 0, void_context_p); + exp = parse_exp_in_context (&string, 0, 0, void_context_p, parse_context); if (*string != '\000') error (_("Junk after end of expression.")); return exp; Index: mi/mi-main.c =================================================================== --- mi/mi-main.c (revision 6) +++ mi/mi-main.c (revision 7) @@ -44,6 +44,7 @@ #include "gdb.h" #include "frame.h" #include "mi-main.h" +#include "language.h" #include #include @@ -693,7 +694,7 @@ mi_cmd_data_evaluate_expression (char *c return MI_CMD_ERROR; } - expr = parse_expression (argv[0]); + expr = parse_expression (argv[0], current_parse_context); old_chain = make_cleanup (free_current_contents, &expr); Index: varobj.c =================================================================== --- varobj.c (revision 6) +++ varobj.c (revision 7) @@ -877,7 +877,7 @@ varobj_set_value (struct varobj *var, ch gdb_assert (varobj_editable_p (var)); input_radix = 10; /* ALWAYS reset to decimal temporarily */ - exp = parse_exp_1 (&s, 0, 0); + exp = parse_exp_1 (&s, 0, 0, wrong_parse_context); if (!gdb_evaluate_expression (exp, &value)) { /* We cannot proceed without a valid expression. */ Index: cli/cli-script.c =================================================================== --- cli/cli-script.c (revision 6) +++ cli/cli-script.c (revision 7) @@ -414,7 +414,7 @@ execute_control_command (struct command_ if (!new_line) break; make_cleanup (free_current_contents, &new_line); - expr = parse_expression (new_line); + expr = parse_expression (new_line, current_parse_context); make_cleanup (free_current_contents, &expr); ret = simple_control; @@ -481,7 +481,7 @@ execute_control_command (struct command_ break; make_cleanup (free_current_contents, &new_line); /* Parse the conditional for the if statement. */ - expr = parse_expression (new_line); + expr = parse_expression (new_line, current_parse_context); make_cleanup (free_current_contents, &expr); current = NULL; Index: expression.h =================================================================== --- expression.h (revision 6) +++ expression.h (revision 7) @@ -419,11 +419,13 @@ extern struct parse_context This macro should be deleted once the transition is complete. */ #define wrong_parse_context (current_parse_context) -extern struct expression *parse_expression (char *); +extern struct expression *parse_expression (char *, struct parse_context); -extern struct expression *parse_expression_in_context (char *, int); +extern struct expression * + parse_expression_in_context (char *, int, struct parse_context); -extern struct expression *parse_exp_1 (char **, struct block *, int); +extern struct expression * + parse_exp_1 (char **, struct block *, int, struct parse_context); /* The innermost context required by the stack and register variables we've encountered so far. To use this, set it to NULL, then call Index: printcmd.c =================================================================== --- printcmd.c (revision 6) +++ printcmd.c (revision 7) @@ -865,7 +865,7 @@ print_command_1 (char *exp, int inspect, if (exp && *exp) { struct type *type; - expr = parse_expression (exp); + expr = parse_expression (exp, wrong_parse_context); old_chain = make_cleanup (free_current_contents, &expr); cleanup = 1; val = evaluate_expression (expr); @@ -950,7 +950,7 @@ output_command (char *exp, int from_tty) format = fmt.format; } - expr = parse_expression (exp); + expr = parse_expression (exp, current_parse_context); old_chain = make_cleanup (free_current_contents, &expr); val = evaluate_expression (expr); @@ -970,7 +970,7 @@ output_command (char *exp, int from_tty) static void set_command (char *exp, int from_tty) { - struct expression *expr = parse_expression (exp); + struct expression *expr = parse_expression (exp, current_parse_context); struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); evaluate_expression (expr); @@ -1272,7 +1272,7 @@ x_command (char *exp, int from_tty) if (exp != 0 && *exp != 0) { - expr = parse_expression (exp); + expr = parse_expression (exp, current_parse_context); /* Cause expression not to be there any more if this command is repeated with Newline. But don't clobber a user-defined command's definition. */ @@ -1367,7 +1367,7 @@ display_command (char *exp, int from_tty } innermost_block = 0; - expr = parse_expression (exp); + expr = parse_expression (exp, current_parse_context); new = (struct display *) xmalloc (sizeof (struct display)); --WIyZ46R2i8wDzkSu--