summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2017-10-18 19:53:21 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2018-01-21 15:15:47 +0000
commitaee1fcdf979d65c7623533ddd6d871767be9de13 (patch)
tree8497a2f48d301efd6d51c648e3b489b7db820b62
parent396af9a1527b396c251e70b5c79b5fc83fd1d7ff (diff)
downloadbinutils-gdb-aee1fcdf979d65c7623533ddd6d871767be9de13.tar.gz
gdb: New API for tracking innermost block
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.
-rw-r--r--gdb/ChangeLog23
-rw-r--r--gdb/ada-exp.y6
-rw-r--r--gdb/ada-lang.c8
-rw-r--r--gdb/breakpoint.c12
-rw-r--r--gdb/c-exp.y20
-rw-r--r--gdb/d-exp.y11
-rw-r--r--gdb/f-exp.y7
-rw-r--r--gdb/go-exp.y7
-rw-r--r--gdb/m2-exp.y14
-rw-r--r--gdb/objfiles.c2
-rw-r--r--gdb/p-exp.y12
-rw-r--r--gdb/parse.c11
-rw-r--r--gdb/parser-defs.h48
-rw-r--r--gdb/printcmd.c8
-rw-r--r--gdb/rust-exp.y8
-rw-r--r--gdb/symfile.c2
-rw-r--r--gdb/varobj.c6
17 files changed, 111 insertions, 94 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a346dddcb2a..d6bf7e3a272 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,28 @@
2018-01-21 Andrew Burgess <andrew.burgess@embecosm.com>
+ * 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.
+
+2018-01-21 Andrew Burgess <andrew.burgess@embecosm.com>
+
* expression.h (innermost_block): Remove declaration.
* varobj.c: Add 'parser-defs.h' include.
diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y
index 0acd1e287e5..56113186b97 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 ab1083830ed..3ff71691248 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..ca5eb023869 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,15 @@ static expression_up parse_exp_in_context_1 (const char **, CORE_ADDR,
const struct block *, int,
int, int *);
+/* Documented at it's declaration. */
+
+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..01ac0cd363a 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -75,9 +75,51 @@ extern const struct block *expression_context_block;
then look up the macro definitions active at that point. */
extern CORE_ADDR expression_context_pc;
-/* The innermost context required by the stack and register variables
- we've encountered so far. */
-extern const struct block *innermost_block;
+/* When parsing expressions we track the innermost block that was
+ referenced. */
+
+class innermost_block_tracker
+{
+public:
+ innermost_block_tracker ()
+ : m_innermost_block (NULL)
+ { /* Nothing. */ }
+
+ /* Reset the currently stored innermost block. Usually called before
+ parsing a new expression. */
+ void reset ()
+ {
+ m_innermost_block = nullptr;
+ }
+
+ /* 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. */
+ void update (const struct block *b);
+
+ /* Overload of main UPDATE method which extracts the block from BS. */
+ void update (const struct block_symbol &bs)
+ {
+ update (bs.block);
+ }
+
+ /* Return the stored innermost block. Can be nullptr if no symbols or
+ registers were found during an expression parse, and so no innermost
+ block was defined. */
+ const struct block *block () const
+ {
+ return m_innermost_block;
+ }
+
+private:
+ /* The currently stored innermost block found while parsing an
+ expression. */
+ const struct block *m_innermost_block;
+};
+
+/* The innermost context required by the stack and register variables 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