Convert go-exp.y to use operations

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

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

	* go-exp.y: Create operations.
	(go_language::parser): Update.
This commit is contained in:
Tom Tromey
2021-03-08 07:27:57 -07:00
parent d182f27979
commit bb4e057488
2 changed files with 117 additions and 101 deletions

View File

@ -1,3 +1,8 @@
2021-03-08 Tom Tromey <tom@tromey.com>
* go-exp.y: Create operations.
(go_language::parser): Update.
2021-03-08 Tom Tromey <tom@tromey.com> 2021-03-08 Tom Tromey <tom@tromey.com>
* objc-lang.c (end_msglist): Create operations. * objc-lang.c (end_msglist): Create operations.

View File

@ -64,6 +64,7 @@
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
#include "charset.h" #include "charset.h"
#include "block.h" #include "block.h"
#include "expop.h"
#define parse_type(ps) builtin_type (ps->gdbarch ()) #define parse_type(ps) builtin_type (ps->gdbarch ())
@ -115,6 +116,8 @@ static void yyerror (const char *);
/* YYSTYPE gets defined by %union. */ /* YYSTYPE gets defined by %union. */
static int parse_number (struct parser_state *, static int parse_number (struct parser_state *,
const char *, int, int, YYSTYPE *); const char *, int, int, YYSTYPE *);
using namespace expr;
%} %}
%type <voidval> exp exp1 type_exp start variable lcurly %type <voidval> exp exp1 type_exp start variable lcurly
@ -193,77 +196,78 @@ start : exp1
; ;
type_exp: type type_exp: type
{ 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); }
; ;
/* Expressions, including the comma operator. */ /* Expressions, including the comma operator. */
exp1 : exp exp1 : exp
| exp1 ',' exp | exp1 ',' exp
{ write_exp_elt_opcode (pstate, BINOP_COMMA); } { pstate->wrap2<comma_operation> (); }
; ;
/* Expressions, not including the comma operator. */ /* Expressions, not including the comma operator. */
exp : '*' exp %prec UNARY exp : '*' exp %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_IND); } { pstate->wrap<unop_ind_operation> (); }
; ;
exp : '&' exp %prec UNARY exp : '&' exp %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_ADDR); } { pstate->wrap<unop_addr_operation> (); }
; ;
exp : '-' exp %prec UNARY exp : '-' exp %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_NEG); } { pstate->wrap<unary_neg_operation> (); }
; ;
exp : '+' exp %prec UNARY exp : '+' exp %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_PLUS); } { pstate->wrap<unary_plus_operation> (); }
; ;
exp : '!' exp %prec UNARY exp : '!' exp %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); } { pstate->wrap<unary_logical_not_operation> (); }
; ;
exp : '^' exp %prec UNARY exp : '^' exp %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_COMPLEMENT); } { pstate->wrap<unary_complement_operation> (); }
; ;
exp : exp INCREMENT %prec UNARY exp : exp INCREMENT %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_POSTINCREMENT); } { pstate->wrap<postinc_operation> (); }
; ;
exp : exp DECREMENT %prec UNARY exp : exp DECREMENT %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_POSTDECREMENT); } { pstate->wrap<postdec_operation> (); }
; ;
/* foo->bar is not in Go. May want as a gdb extension. Later. */ /* foo->bar is not in Go. May want as a gdb extension. Later. */
exp : exp '.' name_not_typename exp : exp '.' name_not_typename
{ write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); {
write_exp_string (pstate, $3.stoken); pstate->push_new<structop_operation>
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } (pstate->pop (), copy_name ($3.stoken));
}
; ;
exp : exp '.' name_not_typename COMPLETE exp : exp '.' name_not_typename COMPLETE
{ pstate->mark_struct_expression (); {
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); structop_base_operation *op
write_exp_string (pstate, $3.stoken); = new structop_operation (pstate->pop (),
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); } copy_name ($3.stoken));
pstate->mark_struct_expression (op);
pstate->push (operation_up (op));
}
; ;
exp : exp '.' COMPLETE exp : exp '.' COMPLETE
{ struct stoken s; {
pstate->mark_struct_expression (); structop_base_operation *op
write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); = new structop_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); }
; ;
exp : exp '[' exp1 ']' exp : exp '[' exp1 ']'
{ write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT); } { pstate->wrap2<subscript_operation> (); }
; ;
exp : exp '(' exp : exp '('
@ -271,10 +275,12 @@ exp : exp '('
being accumulated by an outer function call. */ being accumulated by an outer function call. */
{ pstate->start_arglist (); } { pstate->start_arglist (); }
arglist ')' %prec LEFT_ARROW arglist ')' %prec LEFT_ARROW
{ write_exp_elt_opcode (pstate, OP_FUNCALL); {
write_exp_elt_longcst (pstate, std::vector<operation_up> args
pstate->end_arglist ()); = pstate->pop_vector (pstate->end_arglist ());
write_exp_elt_opcode (pstate, OP_FUNCALL); } pstate->push_new<funcall_operation>
(pstate->pop (), std::move (args));
}
; ;
lcurly : '{' lcurly : '{'
@ -297,15 +303,17 @@ rcurly : '}'
; ;
exp : lcurly type rcurly exp %prec UNARY exp : lcurly type rcurly exp %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_MEMVAL); {
write_exp_elt_type (pstate, $2); pstate->push_new<unop_memval_operation>
write_exp_elt_opcode (pstate, UNOP_MEMVAL); } (pstate->pop (), $2);
}
; ;
exp : type '(' exp ')' %prec UNARY exp : type '(' exp ')' %prec UNARY
{ write_exp_elt_opcode (pstate, UNOP_CAST); {
write_exp_elt_type (pstate, $1); pstate->push_new<unop_cast_operation>
write_exp_elt_opcode (pstate, UNOP_CAST); } (pstate->pop (), $1);
}
; ;
exp : '(' exp1 ')' exp : '(' exp1 ')'
@ -315,100 +323,110 @@ exp : '(' exp1 ')'
/* Binary operators in order of decreasing precedence. */ /* Binary operators in order of decreasing precedence. */
exp : exp '@' exp exp : exp '@' exp
{ write_exp_elt_opcode (pstate, BINOP_REPEAT); } { pstate->wrap2<repeat_operation> (); }
; ;
exp : exp '*' exp exp : exp '*' exp
{ write_exp_elt_opcode (pstate, BINOP_MUL); } { pstate->wrap2<mul_operation> (); }
; ;
exp : exp '/' exp exp : exp '/' exp
{ write_exp_elt_opcode (pstate, BINOP_DIV); } { pstate->wrap2<div_operation> (); }
; ;
exp : exp '%' exp exp : exp '%' exp
{ write_exp_elt_opcode (pstate, BINOP_REM); } { pstate->wrap2<rem_operation> (); }
; ;
exp : exp '+' exp exp : exp '+' exp
{ write_exp_elt_opcode (pstate, BINOP_ADD); } { pstate->wrap2<add_operation> (); }
; ;
exp : exp '-' exp exp : exp '-' exp
{ write_exp_elt_opcode (pstate, BINOP_SUB); } { pstate->wrap2<sub_operation> (); }
; ;
exp : exp LSH exp exp : exp LSH exp
{ write_exp_elt_opcode (pstate, BINOP_LSH); } { pstate->wrap2<lsh_operation> (); }
; ;
exp : exp RSH exp exp : exp RSH exp
{ write_exp_elt_opcode (pstate, BINOP_RSH); } { pstate->wrap2<rsh_operation> (); }
; ;
exp : exp EQUAL exp exp : exp EQUAL exp
{ write_exp_elt_opcode (pstate, BINOP_EQUAL); } { pstate->wrap2<equal_operation> (); }
; ;
exp : exp NOTEQUAL exp exp : exp NOTEQUAL exp
{ write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); } { pstate->wrap2<notequal_operation> (); }
; ;
exp : exp LEQ exp exp : exp LEQ exp
{ write_exp_elt_opcode (pstate, BINOP_LEQ); } { pstate->wrap2<leq_operation> (); }
; ;
exp : exp GEQ exp exp : exp GEQ exp
{ write_exp_elt_opcode (pstate, BINOP_GEQ); } { pstate->wrap2<geq_operation> (); }
; ;
exp : exp '<' exp exp : exp '<' exp
{ write_exp_elt_opcode (pstate, BINOP_LESS); } { pstate->wrap2<less_operation> (); }
; ;
exp : exp '>' exp exp : exp '>' exp
{ write_exp_elt_opcode (pstate, BINOP_GTR); } { pstate->wrap2<gtr_operation> (); }
; ;
exp : exp '&' exp exp : exp '&' exp
{ write_exp_elt_opcode (pstate, BINOP_BITWISE_AND); } { pstate->wrap2<bitwise_and_operation> (); }
; ;
exp : exp '^' exp exp : exp '^' exp
{ write_exp_elt_opcode (pstate, BINOP_BITWISE_XOR); } { pstate->wrap2<bitwise_xor_operation> (); }
; ;
exp : exp '|' exp exp : exp '|' exp
{ write_exp_elt_opcode (pstate, BINOP_BITWISE_IOR); } { pstate->wrap2<bitwise_ior_operation> (); }
; ;
exp : exp ANDAND exp exp : exp ANDAND exp
{ write_exp_elt_opcode (pstate, BINOP_LOGICAL_AND); } { pstate->wrap2<logical_and_operation> (); }
; ;
exp : exp OROR exp exp : exp OROR exp
{ write_exp_elt_opcode (pstate, BINOP_LOGICAL_OR); } { pstate->wrap2<logical_or_operation> (); }
; ;
exp : exp '?' exp ':' exp %prec '?' exp : exp '?' exp ':' exp %prec '?'
{ 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));
}
; ;
exp : exp '=' exp exp : exp '=' exp
{ write_exp_elt_opcode (pstate, BINOP_ASSIGN); } { pstate->wrap2<assign_operation> (); }
; ;
exp : exp ASSIGN_MODIFY exp exp : exp ASSIGN_MODIFY exp
{ 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));
}
; ;
exp : INT exp : INT
{ write_exp_elt_opcode (pstate, OP_LONG); {
write_exp_elt_type (pstate, $1.type); pstate->push_new<long_const_operation>
write_exp_elt_longcst (pstate, (LONGEST)($1.val)); ($1.type, $1.val);
write_exp_elt_opcode (pstate, OP_LONG); } }
; ;
exp : CHAR exp : CHAR
@ -416,7 +434,7 @@ exp : CHAR
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 ($1.type, &vec);
} }
; ;
@ -424,20 +442,20 @@ exp : NAME_OR_INT
{ YYSTYPE val; { YYSTYPE val;
parse_number (pstate, $1.stoken.ptr, parse_number (pstate, $1.stoken.ptr,
$1.stoken.length, 0, &val); $1.stoken.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,
write_exp_elt_longcst (pstate, (LONGEST) val.typed_val_int.val);
val.typed_val_int.val);
write_exp_elt_opcode (pstate, OP_LONG);
} }
; ;
exp : FLOAT exp : FLOAT
{ 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);
}
; ;
exp : variable exp : variable
@ -445,29 +463,26 @@ exp : variable
exp : DOLLAR_VARIABLE exp : DOLLAR_VARIABLE
{ {
write_dollar_variable (pstate, $1); pstate->push_dollar ($1);
} }
; ;
exp : SIZEOF_KEYWORD '(' type ')' %prec UNARY exp : SIZEOF_KEYWORD '(' type ')' %prec UNARY
{ {
/* TODO(dje): Go objects in structs. */ /* TODO(dje): Go objects in structs. */
write_exp_elt_opcode (pstate, OP_LONG);
/* TODO(dje): What's the right type here? */ /* TODO(dje): What's the right type here? */
write_exp_elt_type struct type *size_type
(pstate, = parse_type (pstate)->builtin_unsigned_int;
parse_type (pstate)->builtin_unsigned_int);
$3 = check_typedef ($3); $3 = check_typedef ($3);
write_exp_elt_longcst (pstate, pstate->push_new<long_const_operation>
(LONGEST) TYPE_LENGTH ($3)); (size_type, (LONGEST) TYPE_LENGTH ($3));
write_exp_elt_opcode (pstate, OP_LONG);
} }
; ;
exp : SIZEOF_KEYWORD '(' exp ')' %prec UNARY exp : SIZEOF_KEYWORD '(' exp ')' %prec UNARY
{ {
/* TODO(dje): Go objects in structs. */ /* TODO(dje): Go objects in structs. */
write_exp_elt_opcode (pstate, UNOP_SIZEOF); pstate->wrap<unop_sizeof_operation> ();
} }
string_exp: string_exp:
@ -510,8 +525,8 @@ exp : string_exp %prec ABOVE_COMMA
{ {
int i; int i;
write_exp_string_vector (pstate, 0 /*always utf8*/, /* Always utf8. */
&$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);
@ -519,15 +534,11 @@ exp : string_exp %prec ABOVE_COMMA
; ;
exp : TRUE_KEYWORD exp : TRUE_KEYWORD
{ write_exp_elt_opcode (pstate, OP_BOOL); { pstate->push_new<bool_operation> ($1); }
write_exp_elt_longcst (pstate, (LONGEST) $1);
write_exp_elt_opcode (pstate, OP_BOOL); }
; ;
exp : FALSE_KEYWORD exp : FALSE_KEYWORD
{ write_exp_elt_opcode (pstate, OP_BOOL); { pstate->push_new<bool_operation> ($1); }
write_exp_elt_longcst (pstate, (LONGEST) $1);
write_exp_elt_opcode (pstate, OP_BOOL); }
; ;
variable: name_not_typename ENTRY variable: name_not_typename ENTRY
@ -540,9 +551,7 @@ variable: name_not_typename ENTRY
"parameters, not for \"%s\""), "parameters, not for \"%s\""),
copy_name ($1.stoken).c_str ()); copy_name ($1.stoken).c_str ());
write_exp_elt_opcode (pstate, OP_VAR_ENTRY_VALUE); pstate->push_new<var_entry_value_operation> (sym);
write_exp_elt_sym (pstate, sym);
write_exp_elt_opcode (pstate, OP_VAR_ENTRY_VALUE);
} }
; ;
@ -554,10 +563,8 @@ variable: name_not_typename
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>
write_exp_elt_block (pstate, sym.block); (sym.symbol, sym.block);
write_exp_elt_sym (pstate, sym.symbol);
write_exp_elt_opcode (pstate, OP_VAR_VALUE);
} }
else if ($1.is_a_field_of_this) else if ($1.is_a_field_of_this)
{ {
@ -573,7 +580,8 @@ variable: name_not_typename
msymbol = msymbol =
lookup_bound_minimal_symbol (arg.c_str ()); lookup_bound_minimal_symbol (arg.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 () else if (!have_full_symbols ()
&& !have_partial_symbols ()) && !have_partial_symbols ())
error (_("No symbol table is loaded. " error (_("No symbol table is loaded. "
@ -1572,7 +1580,10 @@ go_language::parser (struct parser_state *par_state) const
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