From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id qItACfGY718DTQAAWB0awg (envelope-from ) for ; Fri, 01 Jan 2021 16:49:37 -0500 Received: by simark.ca (Postfix, from userid 112) id 221A21F0C4; Fri, 1 Jan 2021 16:49:37 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED, MAILING_LIST_MULTI,T_DKIM_INVALID,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 8D8A71F071 for ; Fri, 1 Jan 2021 16:49:31 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C962F3938C26; Fri, 1 Jan 2021 21:48:57 +0000 (GMT) Received: from gateway33.websitewelcome.com (gateway33.websitewelcome.com [192.185.146.130]) by sourceware.org (Postfix) with ESMTPS id A2AFD3938C08 for ; Fri, 1 Jan 2021 21:48:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A2AFD3938C08 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tromey.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=tom@tromey.com Received: from cm17.websitewelcome.com (cm17.websitewelcome.com [100.42.49.20]) by gateway33.websitewelcome.com (Postfix) with ESMTP id 4679A27830B3 for ; Fri, 1 Jan 2021 15:48:53 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id vSI1kzbRsDT64vSI1k79VL; Fri, 01 Jan 2021 15:48:53 -0600 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=w7tUXIzomIVXBQ+fDm49pH6Uw1q0O4s9HaD5Hxovimg=; b=s7cz4SXWcAqVc18T31KpV8U4uy dzMXVjkjwA6bCm+qGO0l3KbDjoLsrEzS+0RhYlmfJQLYrHyk+ckZzrhVrJdIjlw5ZgXQmVV5lutaZ 5H65nMwhiVt5Hr5gmXCwsiBF7; Received: from 97-122-81-39.hlrn.qwest.net ([97.122.81.39]:60424 helo=localhost.localdomain) by box5379.bluehost.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1kvSI1-0029vv-1b for gdb-patches@sourceware.org; Fri, 01 Jan 2021 14:48:53 -0700 From: Tom Tromey To: gdb-patches@sourceware.org Subject: [PATCH 174/203] Add operation-related methods to parser_state Date: Fri, 1 Jan 2021 14:46:54 -0700 Message-Id: <20210101214723.1784144-175-tom@tromey.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210101214723.1784144-1-tom@tromey.com> References: <20210101214723.1784144-1-tom@tromey.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - box5379.bluehost.com X-AntiAbuse: Original Domain - sourceware.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tromey.com X-BWhitelist: no X-Source-IP: 97.122.81.39 X-Source-L: No X-Exim-ID: 1kvSI1-0029vv-1b X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 97-122-81-39.hlrn.qwest.net (localhost.localdomain) [97.122.81.39]:60424 X-Source-Auth: tom+tromey.com X-Email-Count: 175 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" This adds several operation-related methods to parser_state. These methods make it more convenient to change the parsers to be operation-based. Because byacc has poor support for C++, a stack of operations is added to parser_state. A parser can push operations, then later pop them for combination into new operations. This approach avoids the memory leaks that would result if raw pointers were used in the parsers, at the cost of parser productions not being type-safe (they can't indicate that they return an operation). This also introduces analogs of some write_exp functions, like write_exp_string_vector, write_dollar_variable, and write_exp_symbol_reference. gdb/ChangeLog 2021-01-01 Tom Tromey * parser-defs.h (struct parser_state) : New methods. : New member. * parse.c (parser_state::push_c_string) (parser_state::push_symbol, parser_state::push_dollar): New methods. --- gdb/ChangeLog | 10 ++++ gdb/parse.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++ gdb/parser-defs.h | 64 ++++++++++++++++++++++++ 3 files changed, 198 insertions(+) diff --git a/gdb/parse.c b/gdb/parse.c index 24258eb2c27..28ac43f0d16 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -545,6 +545,130 @@ parser_state::mark_completion_tag (enum type_code tag, const char *ptr, m_completion_state.expout_completion_name.reset (xstrndup (ptr, length)); } +/* See parser-defs.h. */ + +void +parser_state::push_c_string (int kind, struct stoken_vector *vec) +{ + std::vector data (vec->len); + for (int i = 0; i < vec->len; ++i) + data[i] = std::string (vec->tokens[i].ptr, vec->tokens[i].length); + + push_new ((enum c_string_type_values) kind, + std::move (data)); +} + +/* See parser-defs.h. */ + +void +parser_state::push_symbol (const char *name, struct symbol *sym) +{ + if (sym != nullptr) + push_new (sym, nullptr); + else + { + struct bound_minimal_symbol msymbol = lookup_bound_minimal_symbol (name); + if (msymbol.minsym != NULL) + push_new (msymbol.minsym, + msymbol.objfile); + else if (!have_full_symbols () && !have_partial_symbols ()) + error (_("No symbol table is loaded. Use the \"file\" command.")); + else + error (_("No symbol \"%s\" in current context."), + name); + } +} + +/* See parser-defs.h. */ + +void +parser_state::push_dollar (struct stoken str) +{ + struct block_symbol sym; + struct bound_minimal_symbol msym; + struct internalvar *isym = NULL; + std::string copy; + + /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1) + and $$digits (equivalent to $<-digits> if you could type that). */ + + int negate = 0; + int i = 1; + /* Double dollar means negate the number and add -1 as well. + Thus $$ alone means -1. */ + if (str.length >= 2 && str.ptr[1] == '$') + { + negate = 1; + i = 2; + } + if (i == str.length) + { + /* Just dollars (one or two). */ + i = -negate; + goto handle_last; + } + /* Is the rest of the token digits? */ + for (; i < str.length; i++) + if (!(str.ptr[i] >= '0' && str.ptr[i] <= '9')) + break; + if (i == str.length) + { + i = atoi (str.ptr + 1 + negate); + if (negate) + i = -i; + goto handle_last; + } + + /* Handle tokens that refer to machine registers: + $ followed by a register name. */ + i = user_reg_map_name_to_regnum (gdbarch (), + str.ptr + 1, str.length - 1); + if (i >= 0) + goto handle_register; + + /* Any names starting with $ are probably debugger internal variables. */ + + copy = copy_name (str); + isym = lookup_only_internalvar (copy.c_str () + 1); + if (isym) + { + push_new (isym); + return; + } + + /* On some systems, such as HP-UX and hppa-linux, certain system routines + have names beginning with $ or $$. Check for those, first. */ + + sym = lookup_symbol (copy.c_str (), NULL, VAR_DOMAIN, NULL); + if (sym.symbol) + { + push_new (sym.symbol, sym.block); + return; + } + msym = lookup_bound_minimal_symbol (copy.c_str ()); + if (msym.minsym) + { + push_new (msym.minsym, msym.objfile); + return; + } + + /* Any other names are assumed to be debugger internal variables. */ + + push_new + (create_internalvar (copy.c_str () + 1)); + return; +handle_last: + push_new (i); + return; +handle_register: + str.length--; + str.ptr++; + push_new (copy_name (str)); + block_tracker->update (expression_context_block, + INNERMOST_BLOCK_FOR_REGISTERS); + return; +} + /* Recognize tokens that start with '$'. These include: diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index f4cce3dfb91..8ddbac2c134 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -25,6 +25,7 @@ #include "expression.h" #include "symtab.h" +#include "expop.h" struct block; struct language_defn; @@ -172,6 +173,66 @@ struct parser_state : public expr_builder void mark_completion_tag (enum type_code tag, const char *ptr, int length); + /* Push an operation on the stack. */ + void push (expr::operation_up &&op) + { + m_operations.push_back (std::move (op)); + } + + /* Create a new operation and push it on the stack. */ + template + void push_new (Arg... args) + { + m_operations.emplace_back (new T (std::forward (args)...)); + } + + /* Push a new C string operation. */ + void push_c_string (int, struct stoken_vector *vec); + + /* Push a symbol reference. If SYM is nullptr, look for a minimal + symbol. */ + void push_symbol (const char *name, struct symbol *sym); + + /* Push a reference to $mumble. This may result in a convenience + variable, a history reference, or a register. */ + void push_dollar (struct stoken str); + + /* Pop an operation from the stack. */ + expr::operation_up pop () + { + expr::operation_up result = std::move (m_operations.back ()); + m_operations.pop_back (); + return result; + } + + /* Pop N elements from the stack and return a vector. */ + std::vector pop_vector (int n) + { + std::vector result (n); + for (int i = 1; i <= n; ++i) + result[n - i] = pop (); + return result; + } + + /* A helper that pops an operation, wraps it in some other + operation, and pushes it again. */ + template + void wrap () + { + using namespace expr; + operation_up v = ::expr::make_operation (pop ()); + push (std::move (v)); + } + + /* A helper that pops two operations, wraps them in some other + operation, and pushes the result. */ + template + void wrap2 () + { + expr::operation_up rhs = pop (); + expr::operation_up lhs = pop (); + push (expr::make_operation (std::move (lhs), std::move (rhs))); + } /* If this is nonzero, this block is used as the lexical context for symbol names. */ @@ -220,6 +281,9 @@ struct parser_state : public expr_builder arguments contain other function calls. */ std::vector m_funcall_chain; + + /* Stack of operations. */ + std::vector m_operations; }; /* When parsing expressions we track the innermost block that was -- 2.26.2