Patchwork [PATCHv5,2/5] gdb: New API for tracking innermost block

login
register
mail settings
Submitter Andrew Burgess
Date Jan. 2, 2018, 3:31 p.m.
Message ID <3397c5b194298a45bc9a58cee8b89b48b77babb7.1514905848.git.andrew.burgess@embecosm.com>
Download mbox | patch
Permalink /patch/25179/
State New
Headers show

Comments

Andrew Burgess - Jan. 2, 2018, 3:31 p.m.
This commit is preparation for a later change, at this point there
should be no user visible change.

We currently maintain a global innermost_block which tracks the most
inner block encountered when parsing an expression.

This commit wraps the innermost_block into a new class, and switches all
direct accesses to the variable to use the class API.

gdb/ChangeLog:

	* ada-exp.y (write_var_from_sym): Switch to innermost_block API.
	* ada-lang.c (resolve_subexp): Likewise.
	* breakpoint.c (set_breakpoint_condition) Likewise.
	(watch_command_1) Likewise.
	* c-exp.y (variable): Likewise.
	* d-exp.y (PrimaryExpression): Likewise.
	* f-exp.y (variable): Likewise.
	* go-exp.y (variable): Likewise.
	* m2-exp.y (variable): Likewise.
	* objfiles.c (objfile::~objfile): Likewise.
	* p-exp.y (variable): Likewise.
	* parse.c (innermost_block): Change type.
	* parser-defs.h (class innermost_block_tracker): New.
	(innermost_block): Change to innermost_block_tracker.
	* printcmd.c (display_command): Switch to innermost_block API.
	(do_one_display): Likewise.
	* rust-exp.y (do_one_display): Likewise.
	* symfile.c (clear_symtab_users): Likewise.
	* varobj.c (varobj_create): Switch to innermost_block API, replace
	use of innermost_block with block stored on varobj object.
---
 gdb/ChangeLog     | 23 +++++++++++++++++++++++
 gdb/ada-exp.y     |  6 +-----
 gdb/ada-lang.c    |  8 ++------
 gdb/breakpoint.c  | 12 ++++++------
 gdb/c-exp.y       | 20 ++++----------------
 gdb/d-exp.y       | 11 ++---------
 gdb/f-exp.y       |  7 +------
 gdb/go-exp.y      |  7 +------
 gdb/m2-exp.y      | 14 ++------------
 gdb/objfiles.c    |  2 +-
 gdb/p-exp.y       | 12 ++----------
 gdb/parse.c       | 13 ++++++++++++-
 gdb/parser-defs.h | 36 ++++++++++++++++++++++++++++++++++--
 gdb/printcmd.c    |  8 ++++----
 gdb/rust-exp.y    |  8 +++-----
 gdb/symfile.c     |  2 +-
 gdb/varobj.c      |  6 +++---
 17 files changed, 102 insertions(+), 93 deletions(-)

Patch

diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
index 0e6010816b5..fa7a4d5b4e8 100644
--- a/gdb/ada-exp.y
+++ b/gdb/ada-exp.y
@@ -757,11 +757,7 @@  write_var_from_sym (struct parser_state *par_state,
 		    struct symbol *sym)
 {
   if (symbol_read_needs_frame (sym))
-    {
-      if (innermost_block == 0
-	  || contained_in (block, innermost_block))
-	innermost_block = block;
-    }
+    innermost_block.update (block);
 
   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 851e69ac4ba..481a29faad2 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -3507,9 +3507,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;
-          if (innermost_block == NULL
-              || contained_in (candidates[i].block, innermost_block))
-            innermost_block = candidates[i].block;
+	  innermost_block.update (candidates[i]);
         }
 
       if (deprocedure_p
@@ -3554,9 +3552,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;
-            if (innermost_block == NULL
-                || contained_in (candidates[i].block, innermost_block))
-              innermost_block = candidates[i].block;
+	    innermost_block.update (candidates[i]);
           }
       }
       break;
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 2b5eebbbee8..91ecca62fc6 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -879,12 +879,12 @@  set_breakpoint_condition (struct breakpoint *b, const char *exp,
 	{
 	  struct watchpoint *w = (struct watchpoint *) b;
 
-	  innermost_block = NULL;
+	  innermost_block.reset ();
 	  arg = exp;
 	  w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
 	  if (*arg)
 	    error (_("Junk at end of expression"));
-	  w->cond_exp_valid_block = innermost_block;
+	  w->cond_exp_valid_block = innermost_block.block ();
 	}
       else
 	{
@@ -10717,7 +10717,7 @@  watch_command_1 (const char *arg, int accessflag, int from_tty,
   /* Parse the rest of the arguments.  From here on out, everything
      is in terms of a newly allocated string instead of the original
      ARG.  */
-  innermost_block = NULL;
+  innermost_block.reset ();
   std::string expression (arg, exp_end - arg);
   exp_start = arg = expression.c_str ();
   expression_up exp = parse_exp_1 (&arg, 0, 0, 0);
@@ -10739,7 +10739,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;
+  exp_valid_block = innermost_block.block ();
   mark = value_mark ();
   fetch_subexp_value (exp.get (), &pc, &val, &result, NULL, just_location);
 
@@ -10777,13 +10777,13 @@  watch_command_1 (const char *arg, int accessflag, int from_tty,
   toklen = end_tok - tok;
   if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
     {
-      innermost_block = NULL;
+      innermost_block.reset ();
       tok = cond_start = end_tok + 1;
       parse_exp_1 (&tok, 0, 0, 0);
 
       /* 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;
+      cond_exp_valid_block = innermost_block.block ();
 
       cond_end = tok;
     }
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 8be13bf9d0c..0482e85ce80 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -949,12 +949,8 @@  variable:	block COLONCOLON name
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
 			  if (symbol_read_needs_frame (sym.symbol))
-			    {
-			      if (innermost_block == 0
-				  || contained_in (sym.block,
-						   innermost_block))
-				innermost_block = sym.block;
-			    }
+
+			    innermost_block.update (sym);
 
 			  write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			  write_exp_elt_block (pstate, sym.block);
@@ -1043,12 +1039,7 @@  variable:	name_not_typename
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				{
-				  if (innermost_block == 0
-				      || contained_in (sym.block,
-						       innermost_block))
-				    innermost_block = sym.block;
-				}
+				innermost_block.update (sym);
 
 			      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			      write_exp_elt_block (pstate, sym.block);
@@ -1060,10 +1051,7 @@  variable:	name_not_typename
 			      /* C++: it hangs off of `this'.  Must
 			         not inadvertently convert from a method call
 				 to data ref.  */
-			      if (innermost_block == 0
-				  || contained_in (sym.block,
-						   innermost_block))
-				innermost_block = sym.block;
+			      innermost_block.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 05b95d5b90d..03be93fbbc7 100644
--- a/gdb/d-exp.y
+++ b/gdb/d-exp.y
@@ -422,12 +422,7 @@  PrimaryExpression:
 		  if (sym.symbol && SYMBOL_CLASS (sym.symbol) != LOC_TYPEDEF)
 		    {
 		      if (symbol_read_needs_frame (sym.symbol))
-			{
-			  if (innermost_block == 0
-			      || contained_in (sym.block, innermost_block))
-			    innermost_block = sym.block;
-			}
-
+			innermost_block.update (sym);
 		      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 		      write_exp_elt_block (pstate, sym.block);
 		      write_exp_elt_sym (pstate, sym.symbol);
@@ -437,9 +432,7 @@  PrimaryExpression:
 		     {
 		      /* It hangs off of `this'.  Must not inadvertently convert from a
 			 method call to data ref.  */
-		      if (innermost_block == 0
-			  || contained_in (sym.block, innermost_block))
-			innermost_block = sym.block;
+		      innermost_block.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/f-exp.y b/gdb/f-exp.y
index 6495e03cc55..ffd52cf3b1d 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -461,12 +461,7 @@  variable:	name_not_typename
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				{
-				  if (innermost_block == 0
-				      || contained_in (sym.block,
-						       innermost_block))
-				    innermost_block = sym.block;
-				}
+				innermost_block.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 2eb69d1c1dd..a96e65534fd 100644
--- a/gdb/go-exp.y
+++ b/gdb/go-exp.y
@@ -552,12 +552,7 @@  variable:	name_not_typename
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				{
-				  if (innermost_block == 0
-				      || contained_in (sym.block,
-						       innermost_block))
-				    innermost_block = sym.block;
-				}
+				innermost_block.update (sym);
 
 			      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			      write_exp_elt_block (pstate, sym.block);
diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y
index 9e74a9d3334..2cf026c77a5 100644
--- a/gdb/m2-exp.y
+++ b/gdb/m2-exp.y
@@ -548,12 +548,7 @@  variable:	block COLONCOLON NAME
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
 			  if (symbol_read_needs_frame (sym.symbol))
-			    {
-			      if (innermost_block == 0
-				  || contained_in (sym.block,
-						   innermost_block))
-				innermost_block = sym.block;
-			    }
+			    innermost_block.update (sym);
 
 			  write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			  write_exp_elt_block (pstate, sym.block);
@@ -574,12 +569,7 @@  variable:	NAME
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				{
-				  if (innermost_block == 0 ||
-				      contained_in (sym.block,
-						    innermost_block))
-				    innermost_block = sym.block;
-				}
+				innermost_block.update (sym);
 
 			      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			      write_exp_elt_block (pstate, sym.block);
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 7adaef119d1..70e369b8b4f 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -704,7 +704,7 @@  objfile::~objfile ()
      FIXME: It's not clear which of these are supposed to persist
      between expressions and which ought to be reset each time.  */
   expression_context_block = NULL;
-  innermost_block = NULL;
+  innermost_block.reset ();
 
   /* Check to see if the current_source_symtab belongs to this objfile,
      and if so, call clear_current_source_symtab_and_line.  */
diff --git a/gdb/p-exp.y b/gdb/p-exp.y
index 95a6924adfc..6b857e1a023 100644
--- a/gdb/p-exp.y
+++ b/gdb/p-exp.y
@@ -709,12 +709,7 @@  variable:	name_not_typename
 			  if (sym.symbol)
 			    {
 			      if (symbol_read_needs_frame (sym.symbol))
-				{
-				  if (innermost_block == 0
-				      || contained_in (sym.block,
-						       innermost_block))
-				    innermost_block = sym.block;
-				}
+				innermost_block.update (sym);
 
 			      write_exp_elt_opcode (pstate, OP_VAR_VALUE);
 			      write_exp_elt_block (pstate, sym.block);
@@ -728,10 +723,7 @@  variable:	name_not_typename
 			      /* Object pascal: it hangs off of `this'.  Must
 			         not inadvertently convert from a method call
 				 to data ref.  */
-			      if (innermost_block == 0
-				  || contained_in (sym.block,
-						   innermost_block))
-				innermost_block = sym.block;
+			      innermost_block.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 8b2bb22c76e..042df51bf8a 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -68,7 +68,7 @@  const struct exp_descriptor exp_descriptor_standard =
 /* Global variables declared in parser-defs.h (and commented there).  */
 const struct block *expression_context_block;
 CORE_ADDR expression_context_pc;
-const struct block *innermost_block;
+innermost_block_tracker innermost_block;
 int arglist_len;
 static struct type_stack type_stack;
 const char *lexptr;
@@ -121,6 +121,17 @@  static expression_up parse_exp_in_context_1 (const char **, CORE_ADDR,
 					     const struct block *, int,
 					     int, int *);
 
+
+/* Update the stored innermost block if the new block is more inner than
+   the currently stored block, or if no block is stored yet.  */
+
+void
+innermost_block_tracker::update (const struct block *b)
+{
+  if (m_innermost_block == NULL || contained_in (b, m_innermost_block))
+    m_innermost_block = b;
+}
+
 /* Data structure for saving values of arglist_len for function calls whose
    arguments contain other function calls.  */
 
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index c537ed4bf7d..5265b394bea 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -75,9 +75,41 @@  extern const struct block *expression_context_block;
    then look up the macro definitions active at that point.  */
 extern CORE_ADDR expression_context_pc;
 
+/* When parsing expressions we track the innermost block that was
+   referenced.  These functions are described in more detail at their
+   definition site.  */
+class innermost_block_tracker
+{
+public:
+  innermost_block_tracker ()
+    : m_innermost_block (NULL)
+  { /* Nothing.  */ }
+
+  void reset ()
+  {
+    m_innermost_block = NULL;
+  }
+
+  void update (const struct block *b);
+
+  void update (const struct block_symbol &bs)
+  {
+    update (bs.block);
+  }
+
+  const struct block *block () const
+  {
+    return m_innermost_block;
+  }
+
+private:
+  const struct block *m_innermost_block;
+};
+
 /* The innermost context required by the stack and register variables
-   we've encountered so far.  */
-extern const struct block *innermost_block;
+   we've encountered so far.  This should be cleared before parsing an
+   expression, and queried once the parse is complete.  */
+extern innermost_block_tracker innermost_block;
 
 /* Number of arguments seen so far in innermost function call.  */
 extern int arglist_len;
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 6256f35baa5..fc9d7e4dd9a 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1723,14 +1723,14 @@  display_command (const char *arg, int from_tty)
       fmt.raw = 0;
     }
 
-  innermost_block = NULL;
+  innermost_block.reset ();
   expression_up expr = parse_expression (exp);
 
   newobj = new display ();
 
   newobj->exp_string = xstrdup (exp);
   newobj->exp = std::move (expr);
-  newobj->block = innermost_block;
+  newobj->block = innermost_block.block ();
   newobj->pspace = current_program_space;
   newobj->number = ++display_number;
   newobj->format = fmt;
@@ -1891,9 +1891,9 @@  do_one_display (struct display *d)
 
       TRY
 	{
-	  innermost_block = NULL;
+	  innermost_block.reset ();
 	  d->exp = parse_expression (d->exp_string);
-	  d->block = innermost_block;
+	  d->block = innermost_block.block ();
 	}
       CATCH (ex, RETURN_MASK_ALL)
 	{
diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y
index 199e87671ee..dcc5fc78eda 100644
--- a/gdb/rust-exp.y
+++ b/gdb/rust-exp.y
@@ -1044,15 +1044,13 @@  super_name (const struct rust_op *ident, unsigned int n_supers)
 		   ident->right.params);
 }
 
-/* A helper that updates innermost_block as appropriate.  */
+/* A helper that updates the innermost block as appropriate.  */
 
 static void
 update_innermost_block (struct block_symbol sym)
 {
-  if (symbol_read_needs_frame (sym.symbol)
-      && (innermost_block == NULL
-	  || contained_in (sym.block, innermost_block)))
-    innermost_block = sym.block;
+  if (symbol_read_needs_frame (sym.symbol))
+    innermost_block.update (sym);
 }
 
 /* A helper to look up a Rust type, or fail.  This only works for
diff --git a/gdb/symfile.c b/gdb/symfile.c
index f7f75b05d32..ab6ec1cdadf 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -2900,7 +2900,7 @@  clear_symtab_users (symfile_add_flags add_flags)
      FIXME: It's not clear which of these are supposed to persist
      between expressions and which ought to be reset each time.  */
   expression_context_block = NULL;
-  innermost_block = NULL;
+  innermost_block.reset ();
 
   /* Varobj may refer to old symbols, perform a cleanup.  */
   varobj_invalidate ();
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 701ef663766..20dd09bd585 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -311,7 +311,7 @@  varobj_create (const char *objname,
 	}
 
       p = expression;
-      innermost_block = NULL;
+      innermost_block.reset ();
       /* Wrap the call to parse expression, so we can 
          return a sensible error.  */
       TRY
@@ -336,7 +336,7 @@  varobj_create (const char *objname,
 	}
 
       var->format = variable_default_display (var.get ());
-      var->root->valid_block = innermost_block;
+      var->root->valid_block = innermost_block.block ();
       var->name = expression;
       /* For a root var, the name and the expr are the same.  */
       var->path_expr = expression;
@@ -345,7 +345,7 @@  varobj_create (const char *objname,
          we must select the appropriate frame before parsing
          the expression, otherwise the value will not be current.
          Since select_frame is so benign, just call it for all cases.  */
-      if (innermost_block)
+      if (var->root->valid_block)
 	{
 	  /* User could specify explicit FRAME-ADDR which was not found but
 	     EXPRESSION is frame specific and we would not be able to evaluate