[13/13] Move innermost_block_tracker global to parse_state

Message ID 20190403013805.11978-14-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey April 3, 2019, 1:38 a.m. UTC
  This changes the parsing API so that callers that are interested in
tracking the innermost block must instantiate an
innermost_block_tracker and pass it in.  Then, a pointer to this
object is stored in the parser_state.

gdb/ChangeLog
2019-04-02  Tom Tromey  <tom@tromey.com>

	* varobj.c (varobj_create): Update.
	* rust-exp.y (struct rust_parser) <update_innermost_block,
	lookup_symbol>: New methods.
	(rust_parser::update_innermost_block, rust_parser::lookup_symbol):
	Rename.
	(rust_parser::rust_lookup_type)
	(rust_parser::convert_ast_to_expression, rust_lex_tests): Update.
	* printcmd.c (display_command, do_one_display): Update.
	* parser-defs.h (struct parser_state) <parser_state>: Add
	"tracker" parameter.
	(block_tracker): New member.
	(class innermost_block_tracker) <innermost_block_tracker>: Add
	"types" parameter.
	<reset>: Remove method.
	(innermost_block): Don't declare.
	(null_post_parser): Update.
	* parse.c (innermost_block): Remove global.
	(write_dollar_variable): Update.
	(parse_exp_1, parse_exp_in_context): Add "tracker" parameter.
	Remove "tracker_types" parameter.
	(parse_expression): Add "tracker" parameter.
	(parse_expression_for_completion): Update.
	(null_post_parser): Add "tracker" parameter.
	* p-exp.y: Update rules.
	* m2-exp.y: Update rules.
	* language.h (struct language_defn) <la_post_parser>: Add
	"tracker" parameter.
	* go-exp.y: Update rules.
	* f-exp.y: Update rules.
	* expression.h (parse_expression, parse_exp_1): Add "tracker"
	parameter.
	* d-exp.y: Update rules.
	* c-exp.y: Update rules.
	* breakpoint.c (set_breakpoint_condition): Create an
	innermost_block_tracker.
	(watch_command_1): Likewise.
	* ada-lang.c (resolve): Add "tracker" parameter.
	(resolve_subexp): Likewise.
	* ada-exp.y (write_var_from_sym): Update.
---
 gdb/ChangeLog     | 42 ++++++++++++++++++++++++++++++++++++++++++
 gdb/ada-exp.y     |  2 +-
 gdb/ada-lang.c    | 31 ++++++++++++++++++-------------
 gdb/breakpoint.c  | 15 +++++++++------
 gdb/c-exp.y       |  7 +++----
 gdb/d-exp.y       |  4 ++--
 gdb/expression.h  |  8 +++++---
 gdb/f-exp.y       |  2 +-
 gdb/go-exp.y      |  2 +-
 gdb/language.h    |  3 ++-
 gdb/m2-exp.y      |  4 ++--
 gdb/p-exp.y       |  4 ++--
 gdb/parse.c       | 36 ++++++++++++++++++------------------
 gdb/parser-defs.h | 34 +++++++++++++---------------------
 gdb/printcmd.c    | 10 ++++++----
 gdb/rust-exp.y    | 29 +++++++++++++++--------------
 gdb/varobj.c      |  9 +++++----
 17 files changed, 145 insertions(+), 97 deletions(-)
  

Patch

diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
index f50500c2e7f..efad85b19ad 100644
--- a/gdb/ada-exp.y
+++ b/gdb/ada-exp.y
@@ -757,7 +757,7 @@  write_var_from_sym (struct parser_state *par_state,
 		    struct symbol *sym)
 {
   if (symbol_read_needs_frame (sym))
-    innermost_block.update (block, INNERMOST_BLOCK_FOR_SYMBOLS);
+    par_state->block_tracker->update (block, INNERMOST_BLOCK_FOR_SYMBOLS);
 
   write_exp_elt_opcode (par_state, OP_VAR_VALUE);
   write_exp_elt_block (par_state, block);
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 6e1c2cbeb3d..51615dcd361 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -125,7 +125,8 @@  static int num_defns_collected (struct obstack *);
 static struct block_symbol *defns_collected (struct obstack *, int);
 
 static struct value *resolve_subexp (expression_up *, int *, int,
-                                     struct type *, int);
+                                     struct type *, int,
+				     innermost_block_tracker *);
 
 static void replace_operator_with_call (expression_up *, int, int, int,
                                         struct symbol *, const struct block *);
@@ -3220,7 +3221,8 @@  ada_decoded_op_name (enum exp_opcode op)
    return type is preferred.  May change (expand) *EXP.  */
 
 static void
-resolve (expression_up *expp, int void_context_p, int parse_completion)
+resolve (expression_up *expp, int void_context_p, int parse_completion,
+	 innermost_block_tracker *tracker)
 {
   struct type *context_type = NULL;
   int pc = 0;
@@ -3228,7 +3230,7 @@  resolve (expression_up *expp, int void_context_p, int parse_completion)
   if (void_context_p)
     context_type = builtin_type ((*expp)->gdbarch)->builtin_void;
 
-  resolve_subexp (expp, &pc, 1, context_type, parse_completion);
+  resolve_subexp (expp, &pc, 1, context_type, parse_completion, tracker);
 }
 
 /* Resolve the operator of the subexpression beginning at
@@ -3242,7 +3244,8 @@  resolve (expression_up *expp, int void_context_p, int parse_completion)
 
 static struct value *
 resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
-                struct type *context_type, int parse_completion)
+                struct type *context_type, int parse_completion,
+		innermost_block_tracker *tracker)
 {
   int pc = *pos;
   int i;
@@ -3267,20 +3270,20 @@  resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
       else
         {
           *pos += 3;
-          resolve_subexp (expp, pos, 0, NULL, parse_completion);
+          resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
         }
       nargs = longest_to_int (exp->elts[pc + 1].longconst);
       break;
 
     case UNOP_ADDR:
       *pos += 1;
-      resolve_subexp (expp, pos, 0, NULL, parse_completion);
+      resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
       break;
 
     case UNOP_QUAL:
       *pos += 3;
       resolve_subexp (expp, pos, 1, check_typedef (exp->elts[pc + 1].type),
-		      parse_completion);
+		      parse_completion, tracker);
       break;
 
     case OP_ATR_MODULUS:
@@ -3311,11 +3314,12 @@  resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
         struct value *arg1;
 
         *pos += 1;
-        arg1 = resolve_subexp (expp, pos, 0, NULL, parse_completion);
+        arg1 = resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
         if (arg1 == NULL)
-          resolve_subexp (expp, pos, 1, NULL, parse_completion);
+          resolve_subexp (expp, pos, 1, NULL, parse_completion, tracker);
         else
-          resolve_subexp (expp, pos, 1, value_type (arg1), parse_completion);
+          resolve_subexp (expp, pos, 1, value_type (arg1), parse_completion,
+			  tracker);
         break;
       }
 
@@ -3403,7 +3407,8 @@  resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
 
   argvec = XALLOCAVEC (struct value *, nargs + 1);
   for (i = 0; i < nargs; i += 1)
-    argvec[i] = resolve_subexp (expp, pos, 1, NULL, parse_completion);
+    argvec[i] = resolve_subexp (expp, pos, 1, NULL, parse_completion,
+				tracker);
   argvec[i] = NULL;
   exp = expp->get ();
 
@@ -3487,7 +3492,7 @@  resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
 
           exp->elts[pc + 1].block = candidates[i].block;
           exp->elts[pc + 2].symbol = candidates[i].symbol;
-	  innermost_block.update (candidates[i]);
+	  tracker->update (candidates[i]);
         }
 
       if (deprocedure_p
@@ -3531,7 +3536,7 @@  resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
 
             exp->elts[pc + 4].block = candidates[i].block;
             exp->elts[pc + 5].symbol = candidates[i].symbol;
-	    innermost_block.update (candidates[i]);
+	    tracker->update (candidates[i]);
           }
       }
       break;
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 855bd3811e2..7799d1c1b48 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -880,11 +880,12 @@  set_breakpoint_condition (struct breakpoint *b, const char *exp,
 	{
 	  struct watchpoint *w = (struct watchpoint *) b;
 
+	  innermost_block_tracker tracker;
 	  arg = exp;
-	  w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
+	  w->cond_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
 	  if (*arg)
 	    error (_("Junk at end of expression"));
-	  w->cond_exp_valid_block = innermost_block.block ();
+	  w->cond_exp_valid_block = tracker.block ();
 	}
       else
 	{
@@ -10603,7 +10604,8 @@  watch_command_1 (const char *arg, int accessflag, int from_tty,
      ARG.  */
   std::string expression (arg, exp_end - arg);
   exp_start = arg = expression.c_str ();
-  expression_up exp = parse_exp_1 (&arg, 0, 0, 0);
+  innermost_block_tracker tracker;
+  expression_up exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
   exp_end = arg;
   /* Remove trailing whitespace from the expression before saving it.
      This makes the eventual display of the expression string a bit
@@ -10622,7 +10624,7 @@  watch_command_1 (const char *arg, int accessflag, int from_tty,
       error (_("Cannot watch constant value `%.*s'."), len, exp_start);
     }
 
-  exp_valid_block = innermost_block.block ();
+  exp_valid_block = tracker.block ();
   struct value *mark = value_mark ();
   struct value *val_as_value = nullptr;
   fetch_subexp_value (exp.get (), &pc, &val_as_value, &result, NULL,
@@ -10663,11 +10665,12 @@  watch_command_1 (const char *arg, int accessflag, int from_tty,
   if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
     {
       tok = cond_start = end_tok + 1;
-      parse_exp_1 (&tok, 0, 0, 0);
+      innermost_block_tracker if_tracker;
+      parse_exp_1 (&tok, 0, 0, 0, &if_tracker);
 
       /* The watchpoint expression may not be local, but the condition
 	 may still be.  E.g.: `watch global if local > 0'.  */
-      cond_exp_valid_block = innermost_block.block ();
+      cond_exp_valid_block = if_tracker.block ();
 
       cond_end = tok;
     }
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 627ea1f3bae..e1a17b5628a 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -1002,8 +1002,7 @@  variable:	block COLONCOLON name
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
 			  if (symbol_read_needs_frame (sym.symbol))
-
-			    innermost_block.update (sym);
+			    pstate->block_tracker->update (sym);
 
 			  write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			  write_exp_elt_block (pstate, sym.block);
@@ -1092,7 +1091,7 @@  variable:	name_not_typename
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				innermost_block.update (sym);
+				pstate->block_tracker->update (sym);
 
 			      /* If we found a function, see if it's
 				 an ifunc resolver that has the same
@@ -1116,7 +1115,7 @@  variable:	name_not_typename
 			      /* C++: it hangs off of `this'.  Must
 			         not inadvertently convert from a method call
 				 to data ref.  */
-			      innermost_block.update (sym);
+			      pstate->block_tracker->update (sym);
 			      write_exp_elt_opcode (pstate, OP_THIS);
 			      write_exp_elt_opcode (pstate, OP_THIS);
 			      write_exp_elt_opcode (pstate, STRUCTOP_PTR);
diff --git a/gdb/d-exp.y b/gdb/d-exp.y
index ca9aaf85802..8f04e93bb8f 100644
--- a/gdb/d-exp.y
+++ b/gdb/d-exp.y
@@ -425,7 +425,7 @@  PrimaryExpression:
 		  if (sym.symbol && SYMBOL_CLASS (sym.symbol) != LOC_TYPEDEF)
 		    {
 		      if (symbol_read_needs_frame (sym.symbol))
-			innermost_block.update (sym);
+			pstate->block_tracker->update (sym);
 		      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 		      write_exp_elt_block (pstate, sym.block);
 		      write_exp_elt_sym (pstate, sym.symbol);
@@ -435,7 +435,7 @@  PrimaryExpression:
 		     {
 		      /* It hangs off of `this'.  Must not inadvertently convert from a
 			 method call to data ref.  */
-		      innermost_block.update (sym);
+		      pstate->block_tracker->update (sym);
 		      write_exp_elt_opcode (pstate, OP_THIS);
 		      write_exp_elt_opcode (pstate, OP_THIS);
 		      write_exp_elt_opcode (pstate, STRUCTOP_PTR);
diff --git a/gdb/expression.h b/gdb/expression.h
index 8ce8c3269e3..10e5f3e788e 100644
--- a/gdb/expression.h
+++ b/gdb/expression.h
@@ -110,7 +110,9 @@  typedef gdb::unique_xmalloc_ptr<expression> expression_up;
 
 /* From parse.c */
 
-extern expression_up parse_expression (const char *);
+class innermost_block_tracker;
+extern expression_up parse_expression (const char *,
+				       innermost_block_tracker * = nullptr);
 
 extern expression_up parse_expression_with_language (const char *string,
 						     enum language lang);
@@ -118,10 +120,10 @@  extern expression_up parse_expression_with_language (const char *string,
 extern struct type *parse_expression_for_completion
     (const char *, gdb::unique_xmalloc_ptr<char> *, enum type_code *);
 
+class innermost_block_tracker;
 extern expression_up parse_exp_1 (const char **, CORE_ADDR pc,
 				  const struct block *, int,
-				  innermost_block_tracker_types
-				    = INNERMOST_BLOCK_FOR_SYMBOLS);
+				  innermost_block_tracker * = nullptr);
 
 /* From eval.c */
 
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 403dfa20687..9ee5316470f 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -480,7 +480,7 @@  variable:	name_not_typename
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				innermost_block.update (sym);
+				pstate->block_tracker->update (sym);
 			      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			      write_exp_elt_block (pstate, sym.block);
 			      write_exp_elt_sym (pstate, sym.symbol);
diff --git a/gdb/go-exp.y b/gdb/go-exp.y
index 771adc4416b..0084b2f7eb6 100644
--- a/gdb/go-exp.y
+++ b/gdb/go-exp.y
@@ -552,7 +552,7 @@  variable:	name_not_typename
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				innermost_block.update (sym);
+				pstate->block_tracker->update (sym);
 
 			      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			      write_exp_elt_block (pstate, sym.block);
diff --git a/gdb/language.h b/gdb/language.h
index 5fc175703a0..a982e1977d2 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -38,6 +38,7 @@  struct lang_varobj_ops;
 struct parser_state;
 class compile_instance;
 struct completion_match_for_lcd;
+class innermost_block_tracker;
 
 #define MAX_FORTRAN_DIMS  7	/* Maximum number of F77 array dims.  */
 
@@ -181,7 +182,7 @@  struct language_defn
        for completion, not evaluation.  */
 
     void (*la_post_parser) (expression_up *expp, int void_context_p,
-			    int completing);
+			    int completing, innermost_block_tracker *tracker);
 
     void (*la_printchar) (int ch, struct type *chtype,
 			  struct ui_file * stream);
diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y
index 3e4bc073801..1ea462ec719 100644
--- a/gdb/m2-exp.y
+++ b/gdb/m2-exp.y
@@ -548,7 +548,7 @@  variable:	block COLONCOLON NAME
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
 			  if (symbol_read_needs_frame (sym.symbol))
-			    innermost_block.update (sym);
+			    pstate->block_tracker->update (sym);
 
 			  write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			  write_exp_elt_block (pstate, sym.block);
@@ -570,7 +570,7 @@  variable:	NAME
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				innermost_block.update (sym);
+				pstate->block_tracker->update (sym);
 
 			      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			      write_exp_elt_block (pstate, sym.block);
diff --git a/gdb/p-exp.y b/gdb/p-exp.y
index 493876815d9..da25ae42af6 100644
--- a/gdb/p-exp.y
+++ b/gdb/p-exp.y
@@ -712,7 +712,7 @@  variable:	name_not_typename
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				innermost_block.update (sym);
+				pstate->block_tracker->update (sym);
 
 			      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			      write_exp_elt_block (pstate, sym.block);
@@ -726,7 +726,7 @@  variable:	name_not_typename
 			      /* Object pascal: it hangs off of `this'.  Must
 			         not inadvertently convert from a method call
 				 to data ref.  */
-			      innermost_block.update (sym);
+			      pstate->block_tracker->update (sym);
 			      write_exp_elt_opcode (pstate, OP_THIS);
 			      write_exp_elt_opcode (pstate, OP_THIS);
 			      write_exp_elt_opcode (pstate, STRUCTOP_PTR);
diff --git a/gdb/parse.c b/gdb/parse.c
index 89a29f0f602..359f6f89321 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -65,10 +65,6 @@  const struct exp_descriptor exp_descriptor_standard =
     evaluate_subexp_standard
   };
 
-/* Global variables declared in parser-defs.h (and commented there).  */
-innermost_block_tracker innermost_block;
-
-
 static unsigned int expressiondebug = 0;
 static void
 show_expressiondebug (struct ui_file *file, int from_tty,
@@ -95,7 +91,7 @@  static int prefixify_subexp (struct expression *, struct expression *, int,
 static expression_up parse_exp_in_context (const char **, CORE_ADDR,
 					   const struct block *, int,
 					   int, int *,
-					   innermost_block_tracker_types,
+					   innermost_block_tracker *,
 					   expr_completion_state *);
 
 static void increase_expout_size (struct expr_builder *ps, size_t lenelt);
@@ -637,8 +633,8 @@  handle_register:
   str.ptr++;
   write_exp_string (ps, str);
   write_exp_elt_opcode (ps, OP_REGISTER);
-  innermost_block.update (ps->expression_context_block,
-			  INNERMOST_BLOCK_FOR_REGISTERS);
+  ps->block_tracker->update (ps->expression_context_block,
+			     INNERMOST_BLOCK_FOR_REGISTERS);
   return;
 }
 
@@ -1049,10 +1045,10 @@  prefixify_subexp (struct expression *inexpr,
 
 expression_up
 parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block,
-	     int comma, innermost_block_tracker_types tracker_types)
+	     int comma, innermost_block_tracker *tracker)
 {
   return parse_exp_in_context (stringptr, pc, block, comma, 0, NULL,
-			       tracker_types, nullptr);
+			       tracker, nullptr);
 }
 
 /* As for parse_exp_1, except that if VOID_CONTEXT_P, then
@@ -1066,20 +1062,22 @@  static expression_up
 parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
 		      const struct block *block,
 		      int comma, int void_context_p, int *out_subexp,
-		      innermost_block_tracker_types tracker_types,
+		      innermost_block_tracker *tracker,
 		      expr_completion_state *cstate)
 {
   const struct language_defn *lang = NULL;
   int subexp;
 
-  innermost_block.reset (tracker_types);
-
   if (*stringptr == 0 || **stringptr == 0)
     error_no_arg (_("expression to compute"));
 
   const struct block *expression_context_block = block;
   CORE_ADDR expression_context_pc = 0;
 
+  innermost_block_tracker local_tracker;
+  if (tracker == nullptr)
+    tracker = &local_tracker;
+
   /* If no context specified, try using the current frame, if any.  */
   if (!expression_context_block)
     expression_context_block = get_selected_block (&expression_context_pc);
@@ -1134,7 +1132,7 @@  parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
 
   parser_state ps (lang, get_current_arch (), expression_context_block,
 		   expression_context_pc, comma, *stringptr,
-		   cstate != nullptr);
+		   cstate != nullptr, tracker);
 
   scoped_restore_current_language lang_saver;
   set_language (lang->la_language);
@@ -1169,7 +1167,8 @@  parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
   if (out_subexp)
     *out_subexp = subexp;
 
-  lang->la_post_parser (&result, void_context_p, ps.parse_completion);
+  lang->la_post_parser (&result, void_context_p, ps.parse_completion,
+			tracker);
 
   if (expressiondebug)
     dump_prefix_expression (result.get (), gdb_stdlog);
@@ -1184,9 +1183,9 @@  parse_exp_in_context (const char **stringptr, CORE_ADDR pc,
    to use up all of the contents of STRING.  */
 
 expression_up
-parse_expression (const char *string)
+parse_expression (const char *string, innermost_block_tracker *tracker)
 {
-  expression_up exp = parse_exp_1 (&string, 0, 0, 0);
+  expression_up exp = parse_exp_1 (&string, 0, 0, 0, tracker);
   if (*string)
     error (_("Junk after end of expression."));
   return exp;
@@ -1228,7 +1227,7 @@  parse_expression_for_completion (const char *string,
   TRY
     {
       exp = parse_exp_in_context (&string, 0, 0, 0, 0, &subexp,
-				  INNERMOST_BLOCK_FOR_SYMBOLS, &cstate);
+				  nullptr, &cstate);
     }
   CATCH (except, RETURN_MASK_ERROR)
     {
@@ -1267,7 +1266,8 @@  parse_expression_for_completion (const char *string,
 /* A post-parser that does nothing.  */
 
 void
-null_post_parser (expression_up *exp, int void_context_p, int completin)
+null_post_parser (expression_up *exp, int void_context_p, int completin,
+		  innermost_block_tracker *tracker)
 {
 }
 
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index edbd3b7b673..5244842e58d 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -29,6 +29,7 @@ 
 struct block;
 struct language_defn;
 struct internalvar;
+class innermost_block_tracker;
 
 extern int parser_debug;
 
@@ -107,13 +108,15 @@  struct parser_state : public expr_builder
 		CORE_ADDR context_pc,
 		int comma,
 		const char *input,
-		int completion)
+		int completion,
+		innermost_block_tracker *tracker)
     : expr_builder (lang, gdbarch),
       expression_context_block (context_block),
       expression_context_pc (context_pc),
       comma_terminates (comma),
       lexptr (input),
-      parse_completion (completion)
+      parse_completion (completion),
+      block_tracker (tracker)
   {
   }
 
@@ -186,6 +189,9 @@  struct parser_state : public expr_builder
   /* Completion state is updated here.  */
   expr_completion_state m_completion_state;
 
+  /* The innermost block tracker.  */
+  innermost_block_tracker *block_tracker;
+
 private:
 
   /* Data structure for saving values of arglist_len for function calls whose
@@ -200,21 +206,12 @@  private:
 class innermost_block_tracker
 {
 public:
-  innermost_block_tracker ()
-    : m_types (INNERMOST_BLOCK_FOR_SYMBOLS),
+  innermost_block_tracker (innermost_block_tracker_types types
+			   = INNERMOST_BLOCK_FOR_SYMBOLS)
+    : m_types (types),
       m_innermost_block (NULL)
   { /* Nothing.  */ }
 
-  /* Reset the currently stored innermost block.  Usually called before
-     parsing a new expression.  As the most common case is that we only
-     want to gather the innermost block for symbols in an expression, this
-     becomes the default block tracker type.  */
-  void reset (innermost_block_tracker_types t = INNERMOST_BLOCK_FOR_SYMBOLS)
-  {
-    m_types = t;
-    m_innermost_block = NULL;
-  }
-
   /* Update the stored innermost block if the new block B is more inner
      than the currently stored block, or if no block is stored yet.  The
      type T tells us whether the block B was for a symbol or for a
@@ -246,12 +243,6 @@  private:
   const struct block *m_innermost_block;
 };
 
-/* The innermost context required by the stack and register variables
-   we've encountered so far.  This is cleared by the expression
-   parsing functions before parsing an expression, and can queried
-   once the parse is complete.  */
-extern innermost_block_tracker innermost_block;
-
 /* A string token, either a char-string or bit-string.  Char-strings are
    used, for example, for the names of symbols.  */
 
@@ -359,7 +350,8 @@  extern int operator_check_standard (struct expression *exp, int pos,
 
 extern const char *op_name_standard (enum exp_opcode);
 
-extern void null_post_parser (expression_up *, int, int);
+extern void null_post_parser (expression_up *, int, int,
+			      innermost_block_tracker *);
 
 extern bool parse_float (const char *p, int len,
 			 const struct type *type, gdb_byte *data);
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index bdaaec81495..be12ef5e636 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1715,13 +1715,14 @@  display_command (const char *arg, int from_tty)
       fmt.raw = 0;
     }
 
-  expression_up expr = parse_expression (exp);
+  innermost_block_tracker tracker;
+  expression_up expr = parse_expression (exp, &tracker);
 
   newobj = new display ();
 
   newobj->exp_string = xstrdup (exp);
   newobj->exp = std::move (expr);
-  newobj->block = innermost_block.block ();
+  newobj->block = tracker.block ();
   newobj->pspace = current_program_space;
   newobj->number = ++display_number;
   newobj->format = fmt;
@@ -1882,8 +1883,9 @@  do_one_display (struct display *d)
 
       TRY
 	{
-	  d->exp = parse_expression (d->exp_string);
-	  d->block = innermost_block.block ();
+	  innermost_block_tracker tracker;
+	  d->exp = parse_expression (d->exp_string, &tracker);
+	  d->block = tracker.block ();
 	}
       CATCH (ex, RETURN_MASK_ALL)
 	{
diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y
index 999ab25f070..6e22620600e 100644
--- a/gdb/rust-exp.y
+++ b/gdb/rust-exp.y
@@ -118,9 +118,6 @@  static int rustyylex (YYSTYPE *, rust_parser *);
 static void rustyyerror (rust_parser *parser, const char *msg);
 
 static struct stoken make_stoken (const char *);
-static struct block_symbol rust_lookup_symbol (const char *name,
-					       const struct block *block,
-					       const domain_enum domain);
 
 /* A regular expression for matching Rust numbers.  This is split up
    since it is very long and this gives us a way to comment the
@@ -241,6 +238,10 @@  struct rust_parser
   int lex_operator (YYSTYPE *lvalp);
   void push_back (char c);
 
+  void update_innermost_block (struct block_symbol sym);
+  struct block_symbol lookup_symbol (const char *name,
+				     const struct block *block,
+				     const domain_enum domain);
   struct type *rust_lookup_type (const char *name, const struct block *block);
   std::vector<struct type *> convert_params_to_types (rust_op_vector *params);
   struct type *convert_ast_to_type (const struct rust_op *operation);
@@ -1104,11 +1105,11 @@  rust_parser::super_name (const struct rust_op *ident, unsigned int n_supers)
 
 /* A helper that updates the innermost block as appropriate.  */
 
-static void
-update_innermost_block (struct block_symbol sym)
+void
+rust_parser::update_innermost_block (struct block_symbol sym)
 {
   if (symbol_read_needs_frame (sym.symbol))
-    innermost_block.update (sym);
+    pstate->block_tracker->update (sym);
 }
 
 /* Lex a hex number with at least MIN digits and at most MAX
@@ -1992,15 +1993,15 @@  munge_name_and_block (const char **name, const struct block **block)
 /* Like lookup_symbol, but handles Rust namespace conventions, and
    doesn't require field_of_this_result.  */
 
-static struct block_symbol
-rust_lookup_symbol (const char *name, const struct block *block,
-		    const domain_enum domain)
+struct block_symbol
+rust_parser::lookup_symbol (const char *name, const struct block *block,
+			    const domain_enum domain)
 {
   struct block_symbol result;
 
   munge_name_and_block (&name, &block);
 
-  result = lookup_symbol (name, block, domain, NULL);
+  result = ::lookup_symbol (name, block, domain, NULL);
   if (result.symbol != NULL)
     update_innermost_block (result);
   return result;
@@ -2016,7 +2017,7 @@  rust_parser::rust_lookup_type (const char *name, const struct block *block)
 
   munge_name_and_block (&name, &block);
 
-  result = lookup_symbol (name, block, STRUCT_DOMAIN, NULL);
+  result = ::lookup_symbol (name, block, STRUCT_DOMAIN, NULL);
   if (result.symbol != NULL)
     {
       update_innermost_block (result);
@@ -2387,8 +2388,8 @@  rust_parser::convert_ast_to_expression (const struct rust_op *operation,
 	  }
 
 	varname = convert_name (operation);
-	sym = rust_lookup_symbol (varname, pstate->expression_context_block,
-				  VAR_DOMAIN);
+	sym = lookup_symbol (varname, pstate->expression_context_block,
+			     VAR_DOMAIN);
 	if (sym.symbol != NULL && SYMBOL_CLASS (sym.symbol) != LOC_TYPEDEF)
 	  {
 	    write_exp_elt_opcode (pstate, OP_VAR_VALUE);
@@ -2726,7 +2727,7 @@  rust_lex_tests (void)
 
   // Set up dummy "parser", so that rust_type works.
   struct parser_state ps (&rust_language_defn, target_gdbarch (),
-			  nullptr, 0, 0, nullptr, 0);
+			  nullptr, 0, 0, nullptr, 0, nullptr);
   rust_parser parser (&ps);
 
   rust_lex_test_one (&parser, "", 0);
diff --git a/gdb/varobj.c b/gdb/varobj.c
index b2975be6b77..abace990494 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -309,13 +309,14 @@  varobj_create (const char *objname,
 	}
 
       p = expression;
+
+      innermost_block_tracker tracker (INNERMOST_BLOCK_FOR_SYMBOLS
+				       | INNERMOST_BLOCK_FOR_REGISTERS);
       /* Wrap the call to parse expression, so we can 
          return a sensible error.  */
       TRY
 	{
-	  var->root->exp = parse_exp_1 (&p, pc, block, 0,
-					INNERMOST_BLOCK_FOR_SYMBOLS
-					| INNERMOST_BLOCK_FOR_REGISTERS);
+	  var->root->exp = parse_exp_1 (&p, pc, block, 0, &tracker);
 	}
 
       CATCH (except, RETURN_MASK_ERROR)
@@ -336,7 +337,7 @@  varobj_create (const char *objname,
 
       var->format = variable_default_display (var.get ());
       var->root->valid_block =
-	var->root->floating ? NULL : innermost_block.block ();
+	var->root->floating ? NULL : tracker.block ();
       var->name = expression;
       /* For a root var, the name and the expr are the same.  */
       var->path_expr = expression;