Avoid side effects in expression lexers
authorTom Tromey <tom@tromey.com>
Fri, 11 Dec 2020 16:59:15 +0000 (09:59 -0700)
committerTom Tromey <tom@tromey.com>
Fri, 11 Dec 2020 17:10:53 +0000 (10:10 -0700)
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.

gdb/ChangeLog
gdb/f-exp.y
gdb/m2-exp.y
gdb/p-exp.y

index a3d977dc604506f5cc1b4ffefef5d108e0fcf2e1..992da3db30223a1f3a17283326c6d57ea21539fb 100644 (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.
index edfbe0cd220279ec5bff53c6a2c071327daf0bb3..ea32056f6dba22657c7a00bf74a7ec09239f64b4 100644 (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.  */
index f6f11126c6901770358ebaf47bb816f17f25665a..d4f3c2c1e455e7347533d309dbf64c61f1e95183 100644 (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 ...
index 9caf15f69f552facae8a26fe04bfcac746662c74..618557c472aa47e01248eb7659da517468cdf551 100644 (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;
-
-                            mark = value_mark ();
-                            val = value_of_internalvar (pstate->gdbarch (),
-                                                        intvar);
-                            current_type = value_type (val);
-                            value_release_to_mark (mark);
-                          }
+                       {
+                         write_dollar_variable (pstate, $1);
+
+                         /* $ 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;
     }