From patchwork Tue Jan 2 15:31:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 25179 Received: (qmail 47031 invoked by alias); 2 Jan 2018 15:32:00 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 46913 invoked by uid 89); 2 Jan 2018 15:32:00 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=10397, 18919, 46112, Junk X-HELO: mail-wm0-f42.google.com Received: from mail-wm0-f42.google.com (HELO mail-wm0-f42.google.com) (74.125.82.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 02 Jan 2018 15:31:56 +0000 Received: by mail-wm0-f42.google.com with SMTP id g130so16761498wme.0 for ; Tue, 02 Jan 2018 07:31:56 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=5YHc+kF4bgMUX4G4k84e7xRqz8p6b95VaItXjwwp9Ak=; b=kj8leoCJnI6ZW6W5dfuKHtVTOfqbmOKlUqWtkxMzz4cSjLxRWVTc/JPToWuWPyiL4z o7tRUEAuT9LZxejGfVr62qcnupRWaLyGM3o2VwqyZ+alR3yg4aIOq1sZdNvYzEkeKoWa LCeZIz4QrkeKxsnVZ2EDdhywB4KaFhQuRJbDh64XSXAjYtJ9B70yeykYnJ+IztqKuaxI gSb72E2IwXov/cUu89BViVL8tUjA4eet3jaAf5yny+B6jzEZxtQvovsdfaKKDPjY/nNX YL4R/fxOcIzyf83q30RWgjVB8cwTvUL/IX2kZO8KH/+gUb9kgF9C9VEVjJdiutEsIsX7 CEQw== X-Gm-Message-State: AKGB3mLv9XzDj9WQosdPDCZDvTk0PczYcOEoO2ajot9e7N2c/mpNDw5g Xg1OTPShoRFapt3n+r7z+Df9Fosi X-Google-Smtp-Source: ACJfBosJoHHqq0jJ3sxMJTfBkvTUacGiVSGlimNXyA7Bu11x9ZO2B9K+DkQXc8xW29v1kmj+BvoV+A== X-Received: by 10.28.145.141 with SMTP id t135mr40644076wmd.107.1514907114039; Tue, 02 Jan 2018 07:31:54 -0800 (PST) Received: from localhost ([81.141.199.69]) by smtp.gmail.com with ESMTPSA id o4sm12674395wra.91.2018.01.02.07.31.53 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 02 Jan 2018 07:31:53 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: donb@codesourcery.com, simark@simark.ca, palves@redhat.com, Andrew Burgess Subject: [PATCHv5 2/5] gdb: New API for tracking innermost block Date: Tue, 2 Jan 2018 15:31:45 +0000 Message-Id: <3397c5b194298a45bc9a58cee8b89b48b77babb7.1514905848.git.andrew.burgess@embecosm.com> In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes 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(-) 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