Avoid side effects in expression lexers

I noticed that some of the lexers were calling write_dollar_variable
from the lexer.  This seems like a bad practice, so this patch moves
the side effects into the parsers.

I tested this by re-running gdb.fortran and gdb.modula2; the Pascal
compiler on my machine seems not to work, so I couldn't test
gdb.pascal.

I note that the type-tracking in the Pascal is also incorrect, in that
a convenience variable's type may change between parsing and
evaluation (or even during the course of evaluation).

gdb/ChangeLog
2020-12-11  Tom Tromey  <tom@tromey.com>

	* p-exp.y (intvar): Remove global.
	(DOLLAR_VARIABLE): Change type.
	(start): Update.
	(exp): Call write_dollar_variable here...
	(yylex): ... not here.
	* m2-exp.y (DOLLAR_VARIABLE): Change type.
	(variable): Call write_dollar_variable here...
	(yylex): ... not here.
	* f-exp.y (DOLLAR_VARIABLE): Change type.
	(exp): Call write_dollar_variable here...
	(yylex): ... not here.
This commit is contained in:
Tom Tromey 2020-12-11 09:59:15 -07:00
parent 14a772212b
commit 02c727013c
4 changed files with 43 additions and 35 deletions

View File

@ -1,3 +1,17 @@
2020-12-11 Tom Tromey <tom@tromey.com>
* p-exp.y (intvar): Remove global.
(DOLLAR_VARIABLE): Change type.
(start): Update.
(exp): Call write_dollar_variable here...
(yylex): ... not here.
* m2-exp.y (DOLLAR_VARIABLE): Change type.
(variable): Call write_dollar_variable here...
(yylex): ... not here.
* f-exp.y (DOLLAR_VARIABLE): Change type.
(exp): Call write_dollar_variable here...
(yylex): ... not here.
2020-12-11 Tom Tromey <tom@tromey.com>
* varobj.c (varobj_create): Update.

View File

@ -174,7 +174,7 @@ static int parse_number (struct parser_state *, const char *, int,
%token SINGLE DOUBLE PRECISION
%token <lval> CHARACTER
%token <voidval> DOLLAR_VARIABLE
%token <sval> DOLLAR_VARIABLE
%token <opcode> ASSIGN_MODIFY
%token <opcode> UNOP_INTRINSIC BINOP_INTRINSIC
@ -509,6 +509,7 @@ exp : variable
;
exp : DOLLAR_VARIABLE
{ write_dollar_variable (pstate, $1); }
;
exp : SIZEOF '(' type ')' %prec UNARY
@ -1357,11 +1358,8 @@ yylex (void)
yylval.sval.length = namelen;
if (*tokstart == '$')
{
write_dollar_variable (pstate, yylval.sval);
return DOLLAR_VARIABLE;
}
return DOLLAR_VARIABLE;
/* Use token-type TYPENAME for symbols that happen to be defined
currently as names of types; NAME for other symbols.
The caller is not constrained to care about the distinction. */

View File

@ -125,7 +125,7 @@ static int number_sign = 1;
/* The GDB scope operator */
%token COLONCOLON
%token <voidval> DOLLAR_VARIABLE
%token <sval> DOLLAR_VARIABLE
/* M2 tokens */
%left ','
@ -535,6 +535,7 @@ variable: fblock
/* GDB internal ($foo) variable */
variable: DOLLAR_VARIABLE
{ write_dollar_variable (pstate, $1); }
;
/* GDB scope operator */
@ -952,10 +953,7 @@ yylex (void)
yylval.sval.length = namelen;
if (*tokstart == '$')
{
write_dollar_variable (pstate, yylval.sval);
return DOLLAR_VARIABLE;
}
return DOLLAR_VARIABLE;
/* Use token-type BLOCKNAME for symbols that happen to be defined as
functions. If this is not so, then ...

View File

@ -115,7 +115,6 @@ static int parse_number (struct parser_state *,
const char *, int, int, YYSTYPE *);
static struct type *current_type;
static struct internalvar *intvar;
static int leftdiv_is_integer;
static void push_current_type (void);
static void pop_current_type (void);
@ -161,7 +160,7 @@ static int search_field;
/* Special type cases, put in to allow the parser to distinguish different
legal basetypes. */
%token <voidval> DOLLAR_VARIABLE
%token <sval> DOLLAR_VARIABLE
/* Object pascal */
@ -192,7 +191,6 @@ static int search_field;
%%
start : { current_type = NULL;
intvar = NULL;
search_field = 0;
leftdiv_is_integer = 0;
}
@ -526,17 +524,28 @@ exp : variable
;
exp : DOLLAR_VARIABLE
/* Already written by write_dollar_variable.
Handle current_type. */
{ if (intvar) {
struct value * val, * mark;
{
write_dollar_variable (pstate, $1);
mark = value_mark ();
val = value_of_internalvar (pstate->gdbarch (),
intvar);
current_type = value_type (val);
value_release_to_mark (mark);
}
/* $ is the normal prefix for pascal
hexadecimal values but this conflicts
with the GDB use for debugger variables
so in expression to enter hexadecimal
values we still need to use C syntax with
0xff */
std::string tmp ($1.ptr, $1.length);
/* Handle current_type. */
struct internalvar *intvar
= lookup_only_internalvar (tmp.c_str () + 1);
if (intvar != nullptr)
{
scoped_value_mark mark;
value *val
= value_of_internalvar (pstate->gdbarch (),
intvar);
current_type = value_type (val);
}
}
;
@ -1494,17 +1503,6 @@ yylex (void)
if (*tokstart == '$')
{
char *tmp;
/* $ is the normal prefix for pascal hexadecimal values
but this conflicts with the GDB use for debugger variables
so in expression to enter hexadecimal values
we still need to use C syntax with 0xff */
write_dollar_variable (pstate, yylval.sval);
tmp = (char *) alloca (namelen + 1);
memcpy (tmp, tokstart, namelen);
tmp[namelen] = '\0';
intvar = lookup_only_internalvar (tmp + 1);
free (uptokstart);
return DOLLAR_VARIABLE;
}