From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id OOEBDf+Y71/2TAAAWB0awg (envelope-from ) for ; Fri, 01 Jan 2021 16:49:51 -0500 Received: by simark.ca (Postfix, from userid 112) id 296661F0B7; Fri, 1 Jan 2021 16:49:51 -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.4 required=5.0 tests=DKIM_SIGNED,MAILING_LIST_MULTI, RCVD_IN_BL_SPAMCOP_NET,T_DKIM_INVALID,URIBL_BLOCKED autolearn=no 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 6F83E1F0C4 for ; Fri, 1 Jan 2021 16:49:38 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BD6A83939C39; Fri, 1 Jan 2021 21:49:05 +0000 (GMT) Received: from gateway22.websitewelcome.com (gateway22.websitewelcome.com [192.185.46.187]) by sourceware.org (Postfix) with ESMTPS id 3835D3939C00 for ; Fri, 1 Jan 2021 21:48:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3835D3939C00 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 cm16.websitewelcome.com (cm16.websitewelcome.com [100.42.49.19]) by gateway22.websitewelcome.com (Postfix) with ESMTP id CCB9A3687 for ; Fri, 1 Jan 2021 15:48:58 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id vSI6kXBHCHPnUvSI6kh001; Fri, 01 Jan 2021 15:48:58 -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=hdqllrteAS26Yd5exqL1d/w477eGMBUq/bXifj4UB8o=; b=VTOZDZexJoThya5bZo93/KmZNS VeUMOSrhJjv8AAsScMr7GTSTPwZJxuUyUvg/uocwH76/+cgh8gPTF+YNTH/v2ynFNzsmsyJrG3E7D K7M1UmM/lxMxHD2Ix1tjJZdMn; Received: from 97-122-81-39.hlrn.qwest.net ([97.122.81.39]:60426 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 1kvSI6-0029zC-Je for gdb-patches@sourceware.org; Fri, 01 Jan 2021 14:48:58 -0700 From: Tom Tromey To: gdb-patches@sourceware.org Subject: [PATCH 184/203] Convert ada-exp.y to use operations Date: Fri, 1 Jan 2021 14:47:04 -0700 Message-Id: <20210101214723.1784144-185-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: 1kvSI6-0029zC-Je X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 97-122-81-39.hlrn.qwest.net (localhost.localdomain) [97.122.81.39]:60426 X-Source-Auth: tom+tromey.com X-Email-Count: 185 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 converts the Ada parser to generate operations rather than exp_elements. This was the most difficult of the parser conversions, partly due to the decision to integrate Ada expression resolution into the parse, and partly due to Ada aggregregate assignment. A couple of new per-parse globals are introduced, along with a number of helper functions. Resolution is done in 'ada_pop', yielding the unfortunate rule that ada-exp.y should generally not use parser_state::pop (exceptions are marked). gdb/ChangeLog 2021-01-01 Tom Tromey * ada-exp.y: Create operations. (empty_stoken): Remove. (ada_pop, ada_wrap, ada_addrof, ada_un_wrap2, ada_wrap2) (ada_wrap_op, ada_wrap3, ada_funcall): New functions. (components): New global. (push_component, choice_component, pop_component, pop_components): New functions. (associations): New global (push_association, pop_association, pop_associations): New functions. (ada_parse): Update. (write_var_from_sym, write_int): Create operations. (write_exp_op_with_string): Remove. (write_object_renaming, write_selectors, write_ambiguous_var) (write_var_or_type, write_name_assoc): Create operations. --- gdb/ChangeLog | 18 ++ gdb/ada-exp.y | 621 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 436 insertions(+), 203 deletions(-) diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y index b55a0b434f7..033bde38d3c 100644 --- a/gdb/ada-exp.y +++ b/gdb/ada-exp.y @@ -47,6 +47,7 @@ #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ #include "frame.h" #include "block.h" +#include "ada-exp.h" #define parse_type(ps) builtin_type (ps->gdbarch ()) @@ -67,8 +68,6 @@ struct name_info { static struct parser_state *pstate = NULL; -static struct stoken empty_stoken = { "", 0 }; - /* If expression is in the context of TYPE'(...), then TYPE, else * NULL. */ static struct type *type_qualifier; @@ -90,9 +89,6 @@ static struct type* write_var_or_type (struct parser_state *, static void write_name_assoc (struct parser_state *, struct stoken); -static void write_exp_op_with_string (struct parser_state *, enum exp_opcode, - struct stoken); - static const struct block *block_lookup (const struct block *, const char *); static LONGEST convert_char_literal (struct type *, LONGEST); @@ -114,6 +110,198 @@ static struct type *type_boolean (struct parser_state *); static struct type *type_system_address (struct parser_state *); +using namespace expr; + +/* Like parser_state::pop, but handles Ada type resolution. + DEPROCEDURE_P and CONTEXT_TYPE are passed to the resolve method, if + called. */ +static operation_up +ada_pop (bool deprocedure_p = true, struct type *context_type = nullptr) +{ + /* Of course it's ok to call parser_state::pop here... */ + operation_up result = pstate->pop (); + ada_resolvable *res = dynamic_cast (result.get ()); + if (res != nullptr + && res->resolve (pstate->expout.get (), + deprocedure_p, + pstate->parse_completion, + pstate->block_tracker, + context_type)) + result + = make_operation (std::move (result), + std::vector ()); + + return result; +} + +/* Like parser_state::wrap, but use ada_pop to pop the value. */ +template +void +ada_wrap () +{ + operation_up arg = ada_pop (); + pstate->push_new (std::move (arg)); +} + +/* Create and push an address-of operation, as appropriate for Ada. + If TYPE is not NULL, the resulting operation will be wrapped in a + cast to TYPE. */ +static void +ada_addrof (struct type *type = nullptr) +{ + operation_up arg = ada_pop (false); + operation_up addr = make_operation (std::move (arg)); + operation_up wrapped + = make_operation (std::move (addr)); + if (type != nullptr) + wrapped = make_operation (std::move (wrapped), type); + pstate->push (std::move (wrapped)); +} + +/* A variant of parser_state::wrap2 that uses ada_pop to pop both + operands, and then pushes a new Ada-wrapped operation of the + template type T. */ +template +void +ada_un_wrap2 () +{ + operation_up rhs = ada_pop (); + operation_up lhs = ada_pop (); + operation_up wrapped = make_operation (std::move (lhs), std::move (rhs)); + pstate->push_new (std::move (wrapped)); +} + +/* A variant of parser_state::wrap2 that uses ada_pop to pop both + operands. Unlike ada_un_wrap2, ada_wrapped_operation is not + used. */ +template +void +ada_wrap2 () +{ + operation_up rhs = ada_pop (); + operation_up lhs = ada_pop (); + pstate->push_new (std::move (lhs), std::move (rhs)); +} + +/* A variant of parser_state::wrap2 that uses ada_pop to pop both + operands. OP is also passed to the constructor of the new binary + operation. */ +template +void +ada_wrap_op (enum exp_opcode op) +{ + operation_up rhs = ada_pop (); + operation_up lhs = ada_pop (); + pstate->push_new (op, std::move (lhs), std::move (rhs)); +} + +/* Pop three operands using ada_pop, then construct a new ternary + operation of type T and push it. */ +template +void +ada_wrap3 () +{ + operation_up rhs = ada_pop (); + operation_up mid = ada_pop (); + operation_up lhs = ada_pop (); + pstate->push_new (std::move (lhs), std::move (mid), std::move (rhs)); +} + +/* Pop NARGS operands, then a callee operand, and use these to + construct and push a new Ada function call operation. */ +static void +ada_funcall (int nargs) +{ + std::vector args (nargs); + for (int i = 0; i < nargs; ++i) + args[nargs - i - 1] = ada_pop (); + /* Call parser_state::pop here, because we don't want to + function-convert the callee slot of a call we're already + constructing. */ + operation_up callee = pstate->pop (); + pstate->push_new (std::move (callee), + std::move (args)); +} + +/* The components being constructed during this parse. */ +static std::vector components; + +/* Create a new ada_component_up of the indicated type and arguments, + and push it on the global 'components' vector. */ +template +void +push_component (Arg... args) +{ + components.emplace_back (new T (std::forward (args)...)); +} + +/* Examine the final element of the 'components' vector, and return it + as a pointer to an ada_choices_component. The caller is + responsible for ensuring that the final element is in fact an + ada_choices_component. */ +static ada_choices_component * +choice_component () +{ + ada_component *last = components.back ().get (); + ada_choices_component *result = dynamic_cast (last); + gdb_assert (result != nullptr); + return result; +} + +/* Pop the most recent component from the global stack, and return + it. */ +static ada_component_up +pop_component () +{ + ada_component_up result = std::move (components.back ()); + components.pop_back (); + return result; +} + +/* Pop the N most recent components from the global stack, and return + them in a vector. */ +static std::vector +pop_components (int n) +{ + std::vector result (n); + for (int i = 1; i <= n; ++i) + result[n - i] = pop_component (); + return result; +} + +/* The associations being constructed during this parse. */ +static std::vector associations; + +/* Create a new ada_association_up of the indicated type and + arguments, and push it on the global 'associations' vector. */ +template +void +push_association (Arg... args) +{ + associations.emplace_back (new T (std::forward (args)...)); +} + +/* Pop the most recent association from the global stack, and return + it. */ +static ada_association_up +pop_association () +{ + ada_association_up result = std::move (associations.back ()); + associations.pop_back (); + return result; +} + +/* Pop the N most recent associations from the global stack, and + return them in a vector. */ +static std::vector +pop_associations (int n) +{ + std::vector result (n); + for (int i = 1; i <= n; ++i) + result[n - i] = pop_association (); + return result; +} + %} %union @@ -135,7 +323,7 @@ static struct type *type_system_address (struct parser_state *); %type positional_list component_groups component_associations %type aggregate_component_list -%type var_or_type +%type var_or_type type_prefix opt_type_prefix %token INT NULL_PTR CHARLIT %token FLOAT @@ -188,43 +376,38 @@ start : exp1 /* Expressions, including the sequencing operator. */ exp1 : exp | exp1 ';' exp - { write_exp_elt_opcode (pstate, BINOP_COMMA); } + { ada_wrap2 (); } | primary ASSIGN exp /* Extension for convenience */ - { write_exp_elt_opcode (pstate, BINOP_ASSIGN); } + { ada_wrap2 (); } ; /* Expressions, not including the sequencing operator. */ primary : primary DOT_ALL - { write_exp_elt_opcode (pstate, UNOP_IND); } + { ada_wrap (); } ; primary : primary DOT_ID - { write_exp_op_with_string (pstate, STRUCTOP_STRUCT, - $2); } + { + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), copy_name ($2)); + } ; primary : primary '(' arglist ')' - { - write_exp_elt_opcode (pstate, OP_FUNCALL); - write_exp_elt_longcst (pstate, $3); - write_exp_elt_opcode (pstate, OP_FUNCALL); - } + { ada_funcall ($3); } | var_or_type '(' arglist ')' { if ($1 != NULL) { if ($3 != 1) error (_("Invalid conversion")); - write_exp_elt_opcode (pstate, UNOP_CAST); - write_exp_elt_type (pstate, $1); - write_exp_elt_opcode (pstate, UNOP_CAST); + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), $1); } else - { - write_exp_elt_opcode (pstate, OP_FUNCALL); - write_exp_elt_longcst (pstate, $3); - write_exp_elt_opcode (pstate, OP_FUNCALL); - } + ada_funcall ($3); } ; @@ -233,9 +416,10 @@ primary : var_or_type '\'' save_qualifier { type_qualifier = $1; } { if ($1 == NULL) error (_("Type required for qualification")); - write_exp_elt_opcode (pstate, UNOP_QUAL); - write_exp_elt_type (pstate, $1); - write_exp_elt_opcode (pstate, UNOP_QUAL); + operation_up arg = ada_pop (true, + check_typedef ($1)); + pstate->push_new + (std::move (arg), $1); type_qualifier = $3; } ; @@ -245,10 +429,10 @@ save_qualifier : { $$ = type_qualifier; } primary : primary '(' simple_exp DOTDOT simple_exp ')' - { write_exp_elt_opcode (pstate, TERNOP_SLICE); } + { ada_wrap3 (); } | var_or_type '(' simple_exp DOTDOT simple_exp ')' { if ($1 == NULL) - write_exp_elt_opcode (pstate, TERNOP_SLICE); + ada_wrap3 (); else error (_("Cannot slice a type")); } @@ -267,38 +451,40 @@ primary : '(' exp1 ')' { } primary : var_or_type %prec VAR { if ($1 != NULL) - { - write_exp_elt_opcode (pstate, OP_TYPE); - write_exp_elt_type (pstate, $1); - write_exp_elt_opcode (pstate, OP_TYPE); - } + pstate->push_new ($1); } ; primary : DOLLAR_VARIABLE /* Various GDB extensions */ - { write_dollar_variable (pstate, $1); } + { pstate->push_dollar ($1); } ; primary : aggregate + { + pstate->push_new + (pop_component ()); + } ; simple_exp : primary ; simple_exp : '-' simple_exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_NEG); } + { ada_wrap (); } ; simple_exp : '+' simple_exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_PLUS); } + { + /* No need to do anything. */ + } ; simple_exp : NOT simple_exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); } + { ada_wrap (); } ; simple_exp : ABS simple_exp %prec UNARY - { write_exp_elt_opcode (pstate, UNOP_ABS); } + { ada_wrap (); } ; arglist : { $$ = 0; } @@ -319,111 +505,114 @@ primary : '{' var_or_type '}' primary %prec '.' { if ($2 == NULL) error (_("Type required within braces in coercion")); - write_exp_elt_opcode (pstate, UNOP_MEMVAL); - write_exp_elt_type (pstate, $2); - write_exp_elt_opcode (pstate, UNOP_MEMVAL); + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), $2); } ; /* Binary operators in order of decreasing precedence. */ simple_exp : simple_exp STARSTAR simple_exp - { write_exp_elt_opcode (pstate, BINOP_EXP); } + { ada_wrap2 (); } ; simple_exp : simple_exp '*' simple_exp - { write_exp_elt_opcode (pstate, BINOP_MUL); } + { ada_wrap2 (); } ; simple_exp : simple_exp '/' simple_exp - { write_exp_elt_opcode (pstate, BINOP_DIV); } + { ada_wrap2 (); } ; simple_exp : simple_exp REM simple_exp /* May need to be fixed to give correct Ada REM */ - { write_exp_elt_opcode (pstate, BINOP_REM); } + { ada_wrap2 (); } ; simple_exp : simple_exp MOD simple_exp - { write_exp_elt_opcode (pstate, BINOP_MOD); } + { ada_wrap2 (); } ; simple_exp : simple_exp '@' simple_exp /* GDB extension */ - { write_exp_elt_opcode (pstate, BINOP_REPEAT); } + { ada_wrap2 (); } ; simple_exp : simple_exp '+' simple_exp - { write_exp_elt_opcode (pstate, BINOP_ADD); } + { ada_wrap_op (BINOP_ADD); } ; simple_exp : simple_exp '&' simple_exp - { write_exp_elt_opcode (pstate, BINOP_CONCAT); } + { ada_wrap2 (); } ; simple_exp : simple_exp '-' simple_exp - { write_exp_elt_opcode (pstate, BINOP_SUB); } + { ada_wrap_op (BINOP_SUB); } ; relation : simple_exp ; relation : simple_exp '=' simple_exp - { write_exp_elt_opcode (pstate, BINOP_EQUAL); } + { ada_wrap_op (BINOP_EQUAL); } ; relation : simple_exp NOTEQUAL simple_exp - { write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); } + { ada_wrap_op (BINOP_NOTEQUAL); } ; relation : simple_exp LEQ simple_exp - { write_exp_elt_opcode (pstate, BINOP_LEQ); } + { ada_un_wrap2 (); } ; relation : simple_exp IN simple_exp DOTDOT simple_exp - { write_exp_elt_opcode (pstate, TERNOP_IN_RANGE); } + { ada_wrap3 (); } | simple_exp IN primary TICK_RANGE tick_arglist - { write_exp_elt_opcode (pstate, BINOP_IN_BOUNDS); - write_exp_elt_longcst (pstate, (LONGEST) $5); - write_exp_elt_opcode (pstate, BINOP_IN_BOUNDS); + { + operation_up rhs = ada_pop (); + operation_up lhs = ada_pop (); + pstate->push_new + (std::move (lhs), std::move (rhs), $5); } | simple_exp IN var_or_type %prec TICK_ACCESS { if ($3 == NULL) error (_("Right operand of 'in' must be type")); - write_exp_elt_opcode (pstate, UNOP_IN_RANGE); - write_exp_elt_type (pstate, $3); - write_exp_elt_opcode (pstate, UNOP_IN_RANGE); + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), $3); } | simple_exp NOT IN simple_exp DOTDOT simple_exp - { write_exp_elt_opcode (pstate, TERNOP_IN_RANGE); - write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); - } + { ada_wrap3 (); + ada_wrap (); } | simple_exp NOT IN primary TICK_RANGE tick_arglist - { write_exp_elt_opcode (pstate, BINOP_IN_BOUNDS); - write_exp_elt_longcst (pstate, (LONGEST) $6); - write_exp_elt_opcode (pstate, BINOP_IN_BOUNDS); - write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); + { + operation_up rhs = ada_pop (); + operation_up lhs = ada_pop (); + pstate->push_new + (std::move (lhs), std::move (rhs), $6); + ada_wrap (); } | simple_exp NOT IN var_or_type %prec TICK_ACCESS { if ($4 == NULL) error (_("Right operand of 'in' must be type")); - write_exp_elt_opcode (pstate, UNOP_IN_RANGE); - write_exp_elt_type (pstate, $4); - write_exp_elt_opcode (pstate, UNOP_IN_RANGE); - write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), $4); + ada_wrap (); } ; relation : simple_exp GEQ simple_exp - { write_exp_elt_opcode (pstate, BINOP_GEQ); } + { ada_un_wrap2 (); } ; relation : simple_exp '<' simple_exp - { write_exp_elt_opcode (pstate, BINOP_LESS); } + { ada_un_wrap2 (); } ; relation : simple_exp '>' simple_exp - { write_exp_elt_opcode (pstate, BINOP_GTR); } + { ada_un_wrap2 (); } ; exp : relation @@ -436,36 +625,36 @@ exp : relation and_exp : relation _AND_ relation - { write_exp_elt_opcode (pstate, BINOP_BITWISE_AND); } + { ada_wrap2 (); } | and_exp _AND_ relation - { write_exp_elt_opcode (pstate, BINOP_BITWISE_AND); } + { ada_wrap2 (); } ; and_then_exp : relation _AND_ THEN relation - { write_exp_elt_opcode (pstate, BINOP_LOGICAL_AND); } + { ada_wrap2 (); } | and_then_exp _AND_ THEN relation - { write_exp_elt_opcode (pstate, BINOP_LOGICAL_AND); } + { ada_wrap2 (); } ; or_exp : relation OR relation - { write_exp_elt_opcode (pstate, BINOP_BITWISE_IOR); } + { ada_wrap2 (); } | or_exp OR relation - { write_exp_elt_opcode (pstate, BINOP_BITWISE_IOR); } + { ada_wrap2 (); } ; or_else_exp : relation OR ELSE relation - { write_exp_elt_opcode (pstate, BINOP_LOGICAL_OR); } + { ada_wrap2 (); } | or_else_exp OR ELSE relation - { write_exp_elt_opcode (pstate, BINOP_LOGICAL_OR); } + { ada_wrap2 (); } ; xor_exp : relation XOR relation - { write_exp_elt_opcode (pstate, BINOP_BITWISE_XOR); } + { ada_wrap2 (); } | xor_exp XOR relation - { write_exp_elt_opcode (pstate, BINOP_BITWISE_XOR); } + { ada_wrap2 (); } ; /* Primaries can denote types (OP_TYPE). In cases such as @@ -477,37 +666,51 @@ xor_exp : relation XOR relation aType'access evaluates to a type that evaluate_subexp attempts to evaluate. */ primary : primary TICK_ACCESS - { write_exp_elt_opcode (pstate, UNOP_ADDR); } + { ada_addrof (); } | primary TICK_ADDRESS - { write_exp_elt_opcode (pstate, UNOP_ADDR); - write_exp_elt_opcode (pstate, UNOP_CAST); - write_exp_elt_type (pstate, - type_system_address (pstate)); - write_exp_elt_opcode (pstate, UNOP_CAST); - } + { ada_addrof (type_system_address (pstate)); } | primary TICK_FIRST tick_arglist - { write_int (pstate, $3, type_int (pstate)); - write_exp_elt_opcode (pstate, OP_ATR_FIRST); } + { + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), OP_ATR_FIRST, $3); + } | primary TICK_LAST tick_arglist - { write_int (pstate, $3, type_int (pstate)); - write_exp_elt_opcode (pstate, OP_ATR_LAST); } + { + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), OP_ATR_LAST, $3); + } | primary TICK_LENGTH tick_arglist - { write_int (pstate, $3, type_int (pstate)); - write_exp_elt_opcode (pstate, OP_ATR_LENGTH); } + { + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), OP_ATR_LENGTH, $3); + } | primary TICK_SIZE - { write_exp_elt_opcode (pstate, OP_ATR_SIZE); } + { ada_wrap (); } | primary TICK_TAG - { write_exp_elt_opcode (pstate, OP_ATR_TAG); } + { ada_wrap (); } | opt_type_prefix TICK_MIN '(' exp ',' exp ')' - { write_exp_elt_opcode (pstate, OP_ATR_MIN); } + { ada_wrap2 (); } | opt_type_prefix TICK_MAX '(' exp ',' exp ')' - { write_exp_elt_opcode (pstate, OP_ATR_MAX); } + { ada_wrap2 (); } | opt_type_prefix TICK_POS '(' exp ')' - { write_exp_elt_opcode (pstate, OP_ATR_POS); } + { ada_wrap (); } | type_prefix TICK_VAL '(' exp ')' - { write_exp_elt_opcode (pstate, OP_ATR_VAL); } + { + operation_up arg = ada_pop (); + pstate->push_new + ($1, std::move (arg)); + } | type_prefix TICK_MODULUS - { write_exp_elt_opcode (pstate, OP_ATR_MODULUS); } + { + struct type *type_arg = check_typedef ($1); + if (!ada_is_modular_type (type_arg)) + error (_("'modulus must be applied to modular type")); + write_int (pstate, ada_modulus (type_arg), + TYPE_TARGET_TYPE (type_arg)); + } ; tick_arglist : %prec '(' @@ -521,18 +724,15 @@ type_prefix : { if ($1 == NULL) error (_("Prefix must be type")); - write_exp_elt_opcode (pstate, OP_TYPE); - write_exp_elt_type (pstate, $1); - write_exp_elt_opcode (pstate, OP_TYPE); } + $$ = $1; + } ; opt_type_prefix : type_prefix + { $$ = $1; } | /* EMPTY */ - { write_exp_elt_opcode (pstate, OP_TYPE); - write_exp_elt_type (pstate, - parse_type (pstate)->builtin_void); - write_exp_elt_opcode (pstate, OP_TYPE); } + { $$ = parse_type (pstate)->builtin_void; } ; @@ -549,10 +749,13 @@ primary : CHARLIT ; primary : FLOAT - { write_exp_elt_opcode (pstate, OP_FLOAT); - write_exp_elt_type (pstate, $1.type); - write_exp_elt_floatcst (pstate, $1.val); - write_exp_elt_opcode (pstate, OP_FLOAT); + { + float_data data; + std::copy (std::begin ($1.val), std::end ($1.val), + std::begin (data)); + pstate->push_new + ($1.type, data); + ada_wrap (); } ; @@ -562,7 +765,8 @@ primary : NULL_PTR primary : STRING { - write_exp_op_with_string (pstate, OP_STRING, $1); + pstate->push_new + (copy_name ($1)); } ; @@ -584,7 +788,7 @@ var_or_type: NAME %prec VAR { $$ = write_var_or_type (pstate, NULL, $1); if ($$ == NULL) - write_exp_elt_opcode (pstate, UNOP_ADDR); + ada_addrof (); else $$ = lookup_pointer_type ($$); } @@ -592,7 +796,7 @@ var_or_type: NAME %prec VAR { $$ = write_var_or_type (pstate, $1, $2); if ($$ == NULL) - write_exp_elt_opcode (pstate, UNOP_ADDR); + ada_addrof (); else $$ = lookup_pointer_type ($$); } @@ -608,18 +812,20 @@ block : NAME COLONCOLON aggregate : '(' aggregate_component_list ')' { - write_exp_elt_opcode (pstate, OP_AGGREGATE); - write_exp_elt_longcst (pstate, $2); - write_exp_elt_opcode (pstate, OP_AGGREGATE); + std::vector components + = pop_components ($2); + + push_component + (std::move (components)); } ; aggregate_component_list : component_groups { $$ = $1; } | positional_list exp - { write_exp_elt_opcode (pstate, OP_POSITIONAL); - write_exp_elt_longcst (pstate, $1); - write_exp_elt_opcode (pstate, OP_POSITIONAL); + { + push_component + ($1, ada_pop ()); $$ = $1 + 1; } | positional_list component_groups @@ -628,15 +834,15 @@ aggregate_component_list : positional_list : exp ',' - { write_exp_elt_opcode (pstate, OP_POSITIONAL); - write_exp_elt_longcst (pstate, 0); - write_exp_elt_opcode (pstate, OP_POSITIONAL); + { + push_component + (0, ada_pop ()); $$ = 1; } | positional_list exp ',' - { write_exp_elt_opcode (pstate, OP_POSITIONAL); - write_exp_elt_longcst (pstate, $1); - write_exp_elt_opcode (pstate, OP_POSITIONAL); + { + push_component + ($1, ada_pop ()); $$ = $1 + 1; } ; @@ -649,15 +855,16 @@ component_groups: ; others : OTHERS ARROW exp - { write_exp_elt_opcode (pstate, OP_OTHERS); } + { + push_component (ada_pop ()); + } ; component_group : component_associations { - write_exp_elt_opcode (pstate, OP_CHOICES); - write_exp_elt_longcst (pstate, $1); - write_exp_elt_opcode (pstate, OP_CHOICES); + ada_choices_component *choices = choice_component (); + choices->set_associations (pop_associations ($1)); } ; @@ -667,36 +874,60 @@ component_group : decisions until after the => or '|', we convert the ambiguity to a resolved shift/reduce conflict. */ component_associations : - NAME ARROW - { write_name_assoc (pstate, $1); } - exp { $$ = 1; } + NAME ARROW exp + { + push_component (ada_pop ()); + write_name_assoc (pstate, $1); + $$ = 1; + } | simple_exp ARROW exp - { $$ = 1; } - | simple_exp DOTDOT simple_exp ARROW - { write_exp_elt_opcode (pstate, OP_DISCRETE_RANGE); - write_exp_op_with_string (pstate, OP_NAME, - empty_stoken); + { + push_component (ada_pop ()); + push_association (ada_pop ()); + $$ = 1; + } + | simple_exp DOTDOT simple_exp ARROW exp + { + push_component (ada_pop ()); + operation_up rhs = ada_pop (); + operation_up lhs = ada_pop (); + push_association + (std::move (lhs), std::move (rhs)); + $$ = 1; + } + | NAME '|' component_associations + { + write_name_assoc (pstate, $1); + $$ = $3 + 1; + } + | simple_exp '|' component_associations + { + push_association (ada_pop ()); + $$ = $3 + 1; + } + | simple_exp DOTDOT simple_exp '|' component_associations + + { + operation_up rhs = ada_pop (); + operation_up lhs = ada_pop (); + push_association + (std::move (lhs), std::move (rhs)); + $$ = $5 + 1; } - exp { $$ = 1; } - | NAME '|' - { write_name_assoc (pstate, $1); } - component_associations { $$ = $4 + 1; } - | simple_exp '|' - component_associations { $$ = $3 + 1; } - | simple_exp DOTDOT simple_exp '|' - { write_exp_elt_opcode (pstate, OP_DISCRETE_RANGE); } - component_associations { $$ = $6 + 1; } ; /* Some extensions borrowed from C, for the benefit of those who find they can't get used to Ada notation in GDB. */ primary : '*' primary %prec '.' - { write_exp_elt_opcode (pstate, UNOP_IND); } + { ada_wrap (); } | '&' primary %prec '.' - { write_exp_elt_opcode (pstate, UNOP_ADDR); } + { ada_addrof (); } | primary '[' exp ']' - { write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT); } + { + ada_wrap2 (); + ada_wrap (); + } ; %% @@ -737,8 +968,18 @@ ada_parse (struct parser_state *par_state) type_qualifier = NULL; obstack_free (&temp_parse_space, NULL); obstack_init (&temp_parse_space); + components.clear (); + associations.clear (); - return yyparse (); + int result = yyparse (); + if (!result) + { + struct type *context_type = nullptr; + if (par_state->void_context_p) + context_type = parse_type (par_state)->builtin_void; + pstate->set_operation (ada_pop (true, context_type)); + } + return result; } static void @@ -758,10 +999,7 @@ write_var_from_sym (struct parser_state *par_state, if (symbol_read_needs_frame (sym)) 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); - write_exp_elt_sym (par_state, sym); - write_exp_elt_opcode (par_state, OP_VAR_VALUE); + par_state->push_new (sym, block); } /* Write integer or boolean constant ARG of type TYPE. */ @@ -769,22 +1007,10 @@ write_var_from_sym (struct parser_state *par_state, static void write_int (struct parser_state *par_state, LONGEST arg, struct type *type) { - write_exp_elt_opcode (par_state, OP_LONG); - write_exp_elt_type (par_state, type); - write_exp_elt_longcst (par_state, arg); - write_exp_elt_opcode (par_state, OP_LONG); + pstate->push_new (type, arg); + ada_wrap (); } -/* Write an OPCODE, string, OPCODE sequence to the current expression. */ -static void -write_exp_op_with_string (struct parser_state *par_state, - enum exp_opcode opcode, struct stoken token) -{ - write_exp_elt_opcode (par_state, opcode); - write_exp_string (par_state, token); - write_exp_elt_opcode (par_state, opcode); -} - /* Emit expression corresponding to the renamed object named * designated by RENAMED_ENTITY[0 .. RENAMED_ENTITY_LEN-1] in the * context of ORIG_LEFT_CONTEXT, to which is applied the operations @@ -852,7 +1078,7 @@ write_object_renaming (struct parser_state *par_state, switch (*renaming_expr) { case 'A': renaming_expr += 1; - write_exp_elt_opcode (par_state, UNOP_IND); + ada_wrap (); break; case 'L': slice_state = LOWER_BOUND; @@ -866,10 +1092,7 @@ write_object_renaming (struct parser_state *par_state, if (next == renaming_expr) goto BadEncoding; renaming_expr = next; - write_exp_elt_opcode (par_state, OP_LONG); - write_exp_elt_type (par_state, type_int (par_state)); - write_exp_elt_longcst (par_state, (LONGEST) val); - write_exp_elt_opcode (par_state, OP_LONG); + write_int (par_state, val, type_int (par_state)); } else { @@ -896,25 +1119,19 @@ write_object_renaming (struct parser_state *par_state, index_sym_info.symbol); } if (slice_state == SIMPLE_INDEX) - { - write_exp_elt_opcode (par_state, OP_FUNCALL); - write_exp_elt_longcst (par_state, (LONGEST) 1); - write_exp_elt_opcode (par_state, OP_FUNCALL); - } + ada_funcall (1); else if (slice_state == LOWER_BOUND) slice_state = UPPER_BOUND; else if (slice_state == UPPER_BOUND) { - write_exp_elt_opcode (par_state, TERNOP_SLICE); + ada_wrap3 (); slice_state = SIMPLE_INDEX; } break; case 'R': { - struct stoken field_name; const char *end; - char *buf; renaming_expr += 1; @@ -923,13 +1140,12 @@ write_object_renaming (struct parser_state *par_state, end = strchr (renaming_expr, 'X'); if (end == NULL) end = renaming_expr + strlen (renaming_expr); - field_name.length = end - renaming_expr; - buf = (char *) malloc (end - renaming_expr + 1); - field_name.ptr = buf; - strncpy (buf, renaming_expr, end - renaming_expr); - buf[end - renaming_expr] = '\000'; + + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), std::string (renaming_expr, + end - renaming_expr)); renaming_expr = end; - write_exp_op_with_string (par_state, STRUCTOP_STRUCT, field_name); break; } @@ -1086,15 +1302,14 @@ write_selectors (struct parser_state *par_state, char *sels) { while (*sels != '\0') { - struct stoken field_name; char *p = chop_separator (sels); sels = p; while (*sels != '\0' && *sels != '.' && (sels[0] != '_' || sels[1] != '_')) sels += 1; - field_name.length = sels - p; - field_name.ptr = p; - write_exp_op_with_string (par_state, STRUCTOP_STRUCT, field_name); + operation_up arg = ada_pop (); + pstate->push_new + (std::move (arg), std::string (p, sels - p)); } } @@ -1112,10 +1327,7 @@ write_ambiguous_var (struct parser_state *par_state, sym->set_linkage_name (obstack_strndup (&temp_parse_space, name, len)); sym->set_language (language_ada, nullptr); - write_exp_elt_opcode (par_state, OP_VAR_VALUE); - write_exp_elt_block (par_state, block); - write_exp_elt_sym (par_state, sym); - write_exp_elt_opcode (par_state, OP_VAR_VALUE); + par_state->push_new (sym, block); } /* A convenient wrapper around ada_get_field_index that takes @@ -1306,7 +1518,8 @@ write_var_or_type (struct parser_state *par_state, = ada_lookup_simple_minsym (encoded_name); if (msym.minsym != NULL) { - write_exp_msymbol (par_state, msym); + par_state->push_new + (msym.minsym, msym.objfile); /* Maybe cause error here rather than later? FIXME? */ write_selectors (par_state, encoded_name + tail_index); return NULL; @@ -1368,13 +1581,15 @@ write_name_assoc (struct parser_state *par_state, struct stoken name) VAR_DOMAIN, &syms); if (nsyms != 1 || SYMBOL_CLASS (syms[0].symbol) == LOC_TYPEDEF) - write_exp_op_with_string (par_state, OP_NAME, name); + pstate->push_new (copy_name (name)); else write_var_from_sym (par_state, syms[0].block, syms[0].symbol); } else if (write_var_or_type (par_state, NULL, name) != NULL) error (_("Invalid use of type.")); + + push_association (ada_pop ()); } /* Convert the character literal whose ASCII value would be VAL to the -- 2.26.2