Convert d-exp.y to use operations

This converts the D parser to generate operations rather than
exp_elements.

gdb/ChangeLog
2021-03-08  Tom Tromey  <tom@tromey.com>

	* d-exp.y: Create operations.
	(d_parse): Update.
This commit is contained in:
Tom Tromey
2021-03-08 07:27:57 -07:00
parent bb4e057488
commit 9412fdcc2a
2 changed files with 134 additions and 120 deletions

View File

@ -1,3 +1,8 @@
2021-03-08 Tom Tromey <tom@tromey.com>
* d-exp.y: Create operations.
(d_parse): Update.
2021-03-08 Tom Tromey <tom@tromey.com> 2021-03-08 Tom Tromey <tom@tromey.com>
* go-exp.y: Create operations. * go-exp.y: Create operations.

View File

@ -52,6 +52,7 @@
#include "charset.h" #include "charset.h"
#include "block.h" #include "block.h"
#include "type-stack.h" #include "type-stack.h"
#include "expop.h"
#define parse_type(ps) builtin_type (ps->gdbarch ()) #define parse_type(ps) builtin_type (ps->gdbarch ())
#define parse_d_type(ps) builtin_d_type (ps->gdbarch ()) #define parse_d_type(ps) builtin_d_type (ps->gdbarch ())
@ -77,6 +78,8 @@ static void yyerror (const char *);
static int type_aggregate_p (struct type *); static int type_aggregate_p (struct type *);
using namespace expr;
%} %}
/* Although the yacc "value" of an expression is not used, /* Although the yacc "value" of an expression is not used,
@ -191,53 +194,63 @@ Expression:
CommaExpression: CommaExpression:
AssignExpression AssignExpression
| AssignExpression ',' CommaExpression | AssignExpression ',' CommaExpression
{ write_exp_elt_opcode (pstate, BINOP_COMMA); } { pstate->wrap2<comma_operation> (); }
; ;
AssignExpression: AssignExpression:
ConditionalExpression ConditionalExpression
| ConditionalExpression '=' AssignExpression | ConditionalExpression '=' AssignExpression
{ write_exp_elt_opcode (pstate, BINOP_ASSIGN); } { pstate->wrap2<assign_operation> (); }
| ConditionalExpression ASSIGN_MODIFY AssignExpression | ConditionalExpression ASSIGN_MODIFY AssignExpression
{ write_exp_elt_opcode (pstate, BINOP_ASSIGN_MODIFY); {
write_exp_elt_opcode (pstate, $2); operation_up rhs = pstate->pop ();
write_exp_elt_opcode (pstate, BINOP_ASSIGN_MODIFY); } operation_up lhs = pstate->pop ();
pstate->push_new<assign_modify_operation>
($2, std::move (lhs), std::move (rhs));
}
; ;
ConditionalExpression: ConditionalExpression:
OrOrExpression OrOrExpression
| OrOrExpression '?' Expression ':' ConditionalExpression | OrOrExpression '?' Expression ':' ConditionalExpression
{ write_exp_elt_opcode (pstate, TERNOP_COND); } {
operation_up last = pstate->pop ();
operation_up mid = pstate->pop ();
operation_up first = pstate->pop ();
pstate->push_new<ternop_cond_operation>
(std::move (first), std::move (mid),
std::move (last));
}
; ;
OrOrExpression: OrOrExpression:
AndAndExpression AndAndExpression
| OrOrExpression OROR AndAndExpression | OrOrExpression OROR AndAndExpression
{ write_exp_elt_opcode (pstate, BINOP_LOGICAL_OR); } { pstate->wrap2<logical_or_operation> (); }
; ;
AndAndExpression: AndAndExpression:
OrExpression OrExpression
| AndAndExpression ANDAND OrExpression | AndAndExpression ANDAND OrExpression
{ write_exp_elt_opcode (pstate, BINOP_LOGICAL_AND); } { pstate->wrap2<logical_and_operation> (); }
; ;
OrExpression: OrExpression:
XorExpression XorExpression
| OrExpression '|' XorExpression | OrExpression '|' XorExpression
{ write_exp_elt_opcode (pstate, BINOP_BITWISE_IOR); } { pstate->wrap2<bitwise_ior_operation> (); }
; ;
XorExpression: XorExpression:
AndExpression AndExpression
| XorExpression '^' AndExpression | XorExpression '^' AndExpression
{ write_exp_elt_opcode (pstate, BINOP_BITWISE_XOR); } { pstate->wrap2<bitwise_xor_operation> (); }
; ;
AndExpression: AndExpression:
CmpExpression CmpExpression
| AndExpression '&' CmpExpression | AndExpression '&' CmpExpression
{ write_exp_elt_opcode (pstate, BINOP_BITWISE_AND); } { pstate->wrap2<bitwise_and_operation> (); }
; ;
CmpExpression: CmpExpression:
@ -249,120 +262,121 @@ CmpExpression:
EqualExpression: EqualExpression:
ShiftExpression EQUAL ShiftExpression ShiftExpression EQUAL ShiftExpression
{ write_exp_elt_opcode (pstate, BINOP_EQUAL); } { pstate->wrap2<equal_operation> (); }
| ShiftExpression NOTEQUAL ShiftExpression | ShiftExpression NOTEQUAL ShiftExpression
{ write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); } { pstate->wrap2<notequal_operation> (); }
; ;
IdentityExpression: IdentityExpression:
ShiftExpression IDENTITY ShiftExpression ShiftExpression IDENTITY ShiftExpression
{ write_exp_elt_opcode (pstate, BINOP_EQUAL); } { pstate->wrap2<equal_operation> (); }
| ShiftExpression NOTIDENTITY ShiftExpression | ShiftExpression NOTIDENTITY ShiftExpression
{ write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); } { pstate->wrap2<notequal_operation> (); }
; ;
RelExpression: RelExpression:
ShiftExpression '<' ShiftExpression ShiftExpression '<' ShiftExpression
{ write_exp_elt_opcode (pstate, BINOP_LESS); } { pstate->wrap2<less_operation> (); }
| ShiftExpression LEQ ShiftExpression | ShiftExpression LEQ ShiftExpression
{ write_exp_elt_opcode (pstate, BINOP_LEQ); } { pstate->wrap2<leq_operation> (); }
| ShiftExpression '>' ShiftExpression | ShiftExpression '>' ShiftExpression
{ write_exp_elt_opcode (pstate, BINOP_GTR); } { pstate->wrap2<gtr_operation> (); }
| ShiftExpression GEQ ShiftExpression | ShiftExpression GEQ ShiftExpression
{ write_exp_elt_opcode (pstate, BINOP_GEQ); } { pstate->wrap2<geq_operation> (); }
; ;
ShiftExpression: ShiftExpression:
AddExpression AddExpression
| ShiftExpression LSH AddExpression | ShiftExpression LSH AddExpression
{ write_exp_elt_opcode (pstate, BINOP_LSH); } { pstate->wrap2<lsh_operation> (); }
| ShiftExpression RSH AddExpression | ShiftExpression RSH AddExpression
{ write_exp_elt_opcode (pstate, BINOP_RSH); } { pstate->wrap2<rsh_operation> (); }
; ;
AddExpression: AddExpression:
MulExpression MulExpression
| AddExpression '+' MulExpression | AddExpression '+' MulExpression
{ write_exp_elt_opcode (pstate, BINOP_ADD); } { pstate->wrap2<add_operation> (); }
| AddExpression '-' MulExpression | AddExpression '-' MulExpression
{ write_exp_elt_opcode (pstate, BINOP_SUB); } { pstate->wrap2<sub_operation> (); }
| AddExpression '~' MulExpression | AddExpression '~' MulExpression
{ write_exp_elt_opcode (pstate, BINOP_CONCAT); } { pstate->wrap2<concat_operation> (); }
; ;
MulExpression: MulExpression:
UnaryExpression UnaryExpression
| MulExpression '*' UnaryExpression | MulExpression '*' UnaryExpression
{ write_exp_elt_opcode (pstate, BINOP_MUL); } { pstate->wrap2<mul_operation> (); }
| MulExpression '/' UnaryExpression | MulExpression '/' UnaryExpression
{ write_exp_elt_opcode (pstate, BINOP_DIV); } { pstate->wrap2<div_operation> (); }
| MulExpression '%' UnaryExpression | MulExpression '%' UnaryExpression
{ write_exp_elt_opcode (pstate, BINOP_REM); } { pstate->wrap2<rem_operation> (); }
UnaryExpression: UnaryExpression:
'&' UnaryExpression '&' UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_ADDR); } { pstate->wrap<unop_addr_operation> (); }
| INCREMENT UnaryExpression | INCREMENT UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_PREINCREMENT); } { pstate->wrap<preinc_operation> (); }
| DECREMENT UnaryExpression | DECREMENT UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_PREDECREMENT); } { pstate->wrap<predec_operation> (); }
| '*' UnaryExpression | '*' UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_IND); } { pstate->wrap<unop_ind_operation> (); }
| '-' UnaryExpression | '-' UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_NEG); } { pstate->wrap<unary_neg_operation> (); }
| '+' UnaryExpression | '+' UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_PLUS); } { pstate->wrap<unary_plus_operation> (); }
| '!' UnaryExpression | '!' UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); } { pstate->wrap<unary_logical_not_operation> (); }
| '~' UnaryExpression | '~' UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_COMPLEMENT); } { pstate->wrap<unary_complement_operation> (); }
| TypeExp '.' SIZEOF_KEYWORD | TypeExp '.' SIZEOF_KEYWORD
{ write_exp_elt_opcode (pstate, UNOP_SIZEOF); } { pstate->wrap<unop_sizeof_operation> (); }
| CastExpression | CastExpression
| PowExpression | PowExpression
; ;
CastExpression: CastExpression:
CAST_KEYWORD '(' TypeExp ')' UnaryExpression CAST_KEYWORD '(' TypeExp ')' UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_CAST_TYPE); } { pstate->wrap2<unop_cast_type_operation> (); }
/* C style cast is illegal D, but is still recognised in /* C style cast is illegal D, but is still recognised in
the grammar, so we keep this around for convenience. */ the grammar, so we keep this around for convenience. */
| '(' TypeExp ')' UnaryExpression | '(' TypeExp ')' UnaryExpression
{ write_exp_elt_opcode (pstate, UNOP_CAST_TYPE); } { pstate->wrap2<unop_cast_type_operation> (); }
; ;
PowExpression: PowExpression:
PostfixExpression PostfixExpression
| PostfixExpression HATHAT UnaryExpression | PostfixExpression HATHAT UnaryExpression
{ write_exp_elt_opcode (pstate, BINOP_EXP); } { pstate->wrap2<exp_operation> (); }
; ;
PostfixExpression: PostfixExpression:
PrimaryExpression PrimaryExpression
| PostfixExpression '.' COMPLETE | PostfixExpression '.' COMPLETE
{ struct stoken s; {
pstate->mark_struct_expression (); structop_base_operation *op
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); = new structop_ptr_operation (pstate->pop (), "");
s.ptr = ""; pstate->mark_struct_expression (op);
s.length = 0; pstate->push (operation_up (op));
write_exp_string (pstate, s); }
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
| PostfixExpression '.' IDENTIFIER | PostfixExpression '.' IDENTIFIER
{ write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); {
write_exp_string (pstate, $3); pstate->push_new<structop_operation>
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } (pstate->pop (), copy_name ($3));
}
| PostfixExpression '.' IDENTIFIER COMPLETE | PostfixExpression '.' IDENTIFIER COMPLETE
{ pstate->mark_struct_expression (); {
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); structop_base_operation *op
write_exp_string (pstate, $3); = new structop_operation (pstate->pop (), copy_name ($3));
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } pstate->mark_struct_expression (op);
pstate->push (operation_up (op));
}
| PostfixExpression '.' SIZEOF_KEYWORD | PostfixExpression '.' SIZEOF_KEYWORD
{ write_exp_elt_opcode (pstate, UNOP_SIZEOF); } { pstate->wrap<unop_sizeof_operation> (); }
| PostfixExpression INCREMENT | PostfixExpression INCREMENT
{ write_exp_elt_opcode (pstate, UNOP_POSTINCREMENT); } { pstate->wrap<postinc_operation> (); }
| PostfixExpression DECREMENT | PostfixExpression DECREMENT
{ write_exp_elt_opcode (pstate, UNOP_POSTDECREMENT); } { pstate->wrap<postdec_operation> (); }
| CallExpression | CallExpression
| IndexExpression | IndexExpression
| SliceExpression | SliceExpression
@ -385,21 +399,25 @@ CallExpression:
PostfixExpression '(' PostfixExpression '('
{ pstate->start_arglist (); } { pstate->start_arglist (); }
ArgumentList_opt ')' ArgumentList_opt ')'
{ write_exp_elt_opcode (pstate, OP_FUNCALL); {
write_exp_elt_longcst (pstate, pstate->end_arglist ()); std::vector<operation_up> args
write_exp_elt_opcode (pstate, OP_FUNCALL); } = pstate->pop_vector (pstate->end_arglist ());
pstate->push_new<funcall_operation>
(pstate->pop (), std::move (args));
}
; ;
IndexExpression: IndexExpression:
PostfixExpression '[' ArgumentList ']' PostfixExpression '[' ArgumentList ']'
{ if (pstate->arglist_len > 0) { if (pstate->arglist_len > 0)
{ {
write_exp_elt_opcode (pstate, MULTI_SUBSCRIPT); std::vector<operation_up> args
write_exp_elt_longcst (pstate, pstate->arglist_len); = pstate->pop_vector (pstate->arglist_len);
write_exp_elt_opcode (pstate, MULTI_SUBSCRIPT); pstate->push_new<multi_subscript_operation>
(pstate->pop (), std::move (args));
} }
else else
write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT); pstate->wrap2<subscript_operation> ();
} }
; ;
@ -407,7 +425,14 @@ SliceExpression:
PostfixExpression '[' ']' PostfixExpression '[' ']'
{ /* Do nothing. */ } { /* Do nothing. */ }
| PostfixExpression '[' AssignExpression DOTDOT AssignExpression ']' | PostfixExpression '[' AssignExpression DOTDOT AssignExpression ']'
{ write_exp_elt_opcode (pstate, TERNOP_SLICE); } {
operation_up last = pstate->pop ();
operation_up mid = pstate->pop ();
operation_up first = pstate->pop ();
pstate->push_new<ternop_slice_operation>
(std::move (first), std::move (mid),
std::move (last));
}
; ;
PrimaryExpression: PrimaryExpression:
@ -427,28 +452,26 @@ PrimaryExpression:
{ {
if (symbol_read_needs_frame (sym.symbol)) if (symbol_read_needs_frame (sym.symbol))
pstate->block_tracker->update (sym); pstate->block_tracker->update (sym);
write_exp_elt_opcode (pstate, OP_VAR_VALUE); pstate->push_new<var_value_operation> (sym.symbol,
write_exp_elt_block (pstate, sym.block); sym.block);
write_exp_elt_sym (pstate, sym.symbol);
write_exp_elt_opcode (pstate, OP_VAR_VALUE);
} }
else if (is_a_field_of_this.type != NULL) else if (is_a_field_of_this.type != NULL)
{ {
/* It hangs off of `this'. Must not inadvertently convert from a /* It hangs off of `this'. Must not inadvertently convert from a
method call to data ref. */ method call to data ref. */
pstate->block_tracker->update (sym); pstate->block_tracker->update (sym);
write_exp_elt_opcode (pstate, OP_THIS); operation_up thisop
write_exp_elt_opcode (pstate, OP_THIS); = make_operation<op_this_operation> ();
write_exp_elt_opcode (pstate, STRUCTOP_PTR); pstate->push_new<structop_ptr_operation>
write_exp_string (pstate, $1); (std::move (thisop), std::move (copy));
write_exp_elt_opcode (pstate, STRUCTOP_PTR);
} }
else else
{ {
/* Lookup foreign name in global static symbols. */ /* Lookup foreign name in global static symbols. */
msymbol = lookup_bound_minimal_symbol (copy.c_str ()); msymbol = lookup_bound_minimal_symbol (copy.c_str ());
if (msymbol.minsym != NULL) if (msymbol.minsym != NULL)
write_exp_msymbol (pstate, msymbol); pstate->push_new<var_msym_value_operation>
(msymbol.minsym, msymbol.objfile);
else if (!have_full_symbols () && !have_partial_symbols ()) else if (!have_full_symbols () && !have_partial_symbols ())
error (_("No symbol table is loaded. Use the \"file\" command")); error (_("No symbol table is loaded. Use the \"file\" command"));
else else
@ -476,9 +499,7 @@ PrimaryExpression:
lookup_symbol (name.c_str (), lookup_symbol (name.c_str (),
(const struct block *) NULL, (const struct block *) NULL,
VAR_DOMAIN, NULL); VAR_DOMAIN, NULL);
write_exp_symbol_reference (pstate, pstate->push_symbol (name.c_str (), sym);
name.c_str (),
sym);
} }
else else
{ {
@ -488,65 +509,54 @@ PrimaryExpression:
error (_("`%s' is not defined as an aggregate type."), error (_("`%s' is not defined as an aggregate type."),
TYPE_SAFE_NAME (type)); TYPE_SAFE_NAME (type));
write_exp_elt_opcode (pstate, OP_SCOPE); pstate->push_new<scope_operation>
write_exp_elt_type (pstate, type); (type, copy_name ($3));
write_exp_string (pstate, $3);
write_exp_elt_opcode (pstate, OP_SCOPE);
} }
} }
| DOLLAR_VARIABLE | DOLLAR_VARIABLE
{ write_dollar_variable (pstate, $1); } { pstate->push_dollar ($1); }
| NAME_OR_INT | NAME_OR_INT
{ YYSTYPE val; { YYSTYPE val;
parse_number (pstate, $1.ptr, $1.length, 0, &val); parse_number (pstate, $1.ptr, $1.length, 0, &val);
write_exp_elt_opcode (pstate, OP_LONG); pstate->push_new<long_const_operation>
write_exp_elt_type (pstate, val.typed_val_int.type); (val.typed_val_int.type, val.typed_val_int.val); }
write_exp_elt_longcst (pstate,
(LONGEST) val.typed_val_int.val);
write_exp_elt_opcode (pstate, OP_LONG); }
| NULL_KEYWORD | NULL_KEYWORD
{ struct type *type = parse_d_type (pstate)->builtin_void; { struct type *type = parse_d_type (pstate)->builtin_void;
type = lookup_pointer_type (type); type = lookup_pointer_type (type);
write_exp_elt_opcode (pstate, OP_LONG); pstate->push_new<long_const_operation> (type, 0); }
write_exp_elt_type (pstate, type);
write_exp_elt_longcst (pstate, (LONGEST) 0);
write_exp_elt_opcode (pstate, OP_LONG); }
| TRUE_KEYWORD | TRUE_KEYWORD
{ write_exp_elt_opcode (pstate, OP_BOOL); { pstate->push_new<bool_operation> (true); }
write_exp_elt_longcst (pstate, (LONGEST) 1);
write_exp_elt_opcode (pstate, OP_BOOL); }
| FALSE_KEYWORD | FALSE_KEYWORD
{ write_exp_elt_opcode (pstate, OP_BOOL); { pstate->push_new<bool_operation> (false); }
write_exp_elt_longcst (pstate, (LONGEST) 0);
write_exp_elt_opcode (pstate, OP_BOOL); }
| INTEGER_LITERAL | INTEGER_LITERAL
{ write_exp_elt_opcode (pstate, OP_LONG); { pstate->push_new<long_const_operation> ($1.type, $1.val); }
write_exp_elt_type (pstate, $1.type);
write_exp_elt_longcst (pstate, (LONGEST)($1.val));
write_exp_elt_opcode (pstate, OP_LONG); }
| FLOAT_LITERAL | FLOAT_LITERAL
{ write_exp_elt_opcode (pstate, OP_FLOAT); {
write_exp_elt_type (pstate, $1.type); float_data data;
write_exp_elt_floatcst (pstate, $1.val); std::copy (std::begin ($1.val), std::end ($1.val),
write_exp_elt_opcode (pstate, OP_FLOAT); } std::begin (data));
pstate->push_new<float_const_operation> ($1.type, data);
}
| CHARACTER_LITERAL | CHARACTER_LITERAL
{ struct stoken_vector vec; { struct stoken_vector vec;
vec.len = 1; vec.len = 1;
vec.tokens = &$1; vec.tokens = &$1;
write_exp_string_vector (pstate, $1.type, &vec); } pstate->push_c_string (0, &vec); }
| StringExp | StringExp
{ int i; { int i;
write_exp_string_vector (pstate, 0, &$1); pstate->push_c_string (0, &$1);
for (i = 0; i < $1.len; ++i) for (i = 0; i < $1.len; ++i)
free ($1.tokens[i].ptr); free ($1.tokens[i].ptr);
free ($1.tokens); } free ($1.tokens); }
| ArrayLiteral | ArrayLiteral
{ write_exp_elt_opcode (pstate, OP_ARRAY); {
write_exp_elt_longcst (pstate, (LONGEST) 0); std::vector<operation_up> args
write_exp_elt_longcst (pstate, (LONGEST) $1 - 1); = pstate->pop_vector ($1);
write_exp_elt_opcode (pstate, OP_ARRAY); } pstate->push_new<array_operation>
(0, $1 - 1, std::move (args));
}
| TYPEOF_KEYWORD '(' Expression ')' | TYPEOF_KEYWORD '(' Expression ')'
{ write_exp_elt_opcode (pstate, OP_TYPEOF); } { pstate->wrap<typeof_operation> (); }
; ;
ArrayLiteral: ArrayLiteral:
@ -595,14 +605,10 @@ TypeExp:
'(' TypeExp ')' '(' TypeExp ')'
{ /* Do nothing. */ } { /* Do nothing. */ }
| BasicType | BasicType
{ write_exp_elt_opcode (pstate, OP_TYPE); { pstate->push_new<type_operation> ($1); }
write_exp_elt_type (pstate, $1);
write_exp_elt_opcode (pstate, OP_TYPE); }
| BasicType BasicType2 | BasicType BasicType2
{ $$ = type_stack->follow_types ($1); { $$ = type_stack->follow_types ($1);
write_exp_elt_opcode (pstate, OP_TYPE); pstate->push_new<type_operation> ($$);
write_exp_elt_type (pstate, $$);
write_exp_elt_opcode (pstate, OP_TYPE);
} }
; ;
@ -1622,7 +1628,10 @@ d_parse (struct parser_state *par_state)
popping = 0; popping = 0;
name_obstack.clear (); name_obstack.clear ();
return yyparse (); int result = yyparse ();
if (!result)
pstate->set_operation (pstate->pop ());
return result;
} }
static void static void