Remove union exp_element

This removes union exp_element functions that either create such
elements or walk them.  struct expression no longer holds
exp_elements.  A couple of language_defn methods are also removed, as
they are obsolete.

Note that this patch also removes the print_expression code.  The only
in-tree caller of this was from dump_prefix_expression, which is only
called when expression debugging is enabled.  Implementing this would
involve a fair amount of code, and it seems to me that prefix dumping
is preferable anyway, as it is unambiguous.  So, I have not
reimplemented this feature.

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

	* value.h (evaluate_subexp_with_coercion): Don't declare.
	* parse.c (exp_descriptor_standard): Remove.
	(expr_builder::expr_builder, expr_builder::release): Update.
	(expression::expression): Remove size_t parameter.
	(expression::~expression): Simplify.
	(expression::resize): Remove.
	(write_exp_elt, write_exp_elt_opcode, write_exp_elt_sym)
	(write_exp_elt_msym, write_exp_elt_block, write_exp_elt_objfile)
	(write_exp_elt_longcst, write_exp_elt_floatcst)
	(write_exp_elt_type, write_exp_elt_intern, write_exp_string)
	(write_exp_string_vector, write_exp_bitstring): Remove.
	* p-lang.h (class pascal_language) <opcode_print_table,
	op_print_tab>: Remove.
	* p-lang.c (pascal_language::op_print_tab): Remove.
	* opencl-lang.c (class opencl_language) <opcode_print_table>:
	Remove.
	* objc-lang.c (objc_op_print_tab): Remove.
	(class objc_language) <opcode_print_table>: Remove.
	* m2-lang.h (class m2_language) <opcode_print_table,
	op_print_tab>: Remove.
	* m2-lang.c (m2_language::op_print_tab): Remove.
	* language.h (struct language_defn) <post_parser, expression_ops,
	opcode_print_table>: Remove.
	* language.c (language_defn::expression_ops)
	(auto_or_unknown_language::opcode_print_table): Remove.
	* go-lang.h (class go_language) <opcode_print_table,
	op_print_tab>: Remove.
	* go-lang.c (go_language::op_print_tab): Remove.
	* f-lang.h (class f_language) <opcode_print_table>: Remove
	<op_print_tab>: Remove.
	* f-lang.c (f_language::op_print_tab): Remove.
	* expression.h (union exp_element): Remove.
	(struct expression): Remove size_t parameter from constructor.
	<resize>: Remove.
	<first_opcode>: Update.
	<nelts, elts>: Remove.
	(EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): Remove.
	(evaluate_subexp_standard, print_expression, op_string)
	(dump_raw_expression): Don't declare.
	* expprint.c (print_expression, print_subexp)
	(print_subexp_funcall, print_subexp_standard, op_string)
	(dump_raw_expression, dump_subexp, dump_subexp_body)
	(dump_subexp_body_funcall, dump_subexp_body_standard): Remove.
	(dump_prefix_expression): Update.
	* eval.c (evaluate_subexp): Remove.
	(evaluate_expression, evaluate_type): Update.
	(evaluate_subexpression_type): Remove.
	(fetch_subexp_value): Remove "pc" parameter.  Update.
	(extract_field_op, evaluate_struct_tuple, evaluate_funcall)
	(evaluate_subexp_standard, evaluate_subexp_for_address)
	(evaluate_subexp_with_coercion, evaluate_subexp_for_sizeof)
	(evaluate_subexp_for_cast): Remove.
	(parse_and_eval_type): Update.
	* dtrace-probe.c (dtrace_probe::compile_to_ax): Update.
	* d-lang.c (d_op_print_tab): Remove.
	(class d_language) <opcode_print_table>: Remove.
	* c-lang.h (c_op_print_tab): Don't declare.
	* c-lang.c (c_op_print_tab): Remove.
	(class c_language, class cplus_language, class asm_language, class
	minimal_language) <opcode_print_table>: Remove.
	* breakpoint.c (update_watchpoint, watchpoint_check)
	(watchpoint_exp_is_const, watch_command_1): Update.
	* ax-gdb.h (union exp_element): Don't declare.
	* ax-gdb.c (const_var_ref, const_expr, maybe_const_expr)
	(gen_repeat, gen_sizeof, gen_expr_for_cast, gen_expr)
	(gen_expr_binop_rest): Remove.
	(gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update.
	* ada-lang.c (ada_op_print_tab): Remove.
	(class ada_language) <post_parser, opcode_print_table>: Remove.
This commit is contained in:
Tom Tromey 2021-03-08 07:27:57 -07:00
parent f2a98603a8
commit 1eaebe02cf
33 changed files with 147 additions and 5316 deletions

View file

@ -1,3 +1,75 @@
2021-03-08 Tom Tromey <tom@tromey.com>
* value.h (evaluate_subexp_with_coercion): Don't declare.
* parse.c (exp_descriptor_standard): Remove.
(expr_builder::expr_builder, expr_builder::release): Update.
(expression::expression): Remove size_t parameter.
(expression::~expression): Simplify.
(expression::resize): Remove.
(write_exp_elt, write_exp_elt_opcode, write_exp_elt_sym)
(write_exp_elt_msym, write_exp_elt_block, write_exp_elt_objfile)
(write_exp_elt_longcst, write_exp_elt_floatcst)
(write_exp_elt_type, write_exp_elt_intern, write_exp_string)
(write_exp_string_vector, write_exp_bitstring): Remove.
* p-lang.h (class pascal_language) <opcode_print_table,
op_print_tab>: Remove.
* p-lang.c (pascal_language::op_print_tab): Remove.
* opencl-lang.c (class opencl_language) <opcode_print_table>:
Remove.
* objc-lang.c (objc_op_print_tab): Remove.
(class objc_language) <opcode_print_table>: Remove.
* m2-lang.h (class m2_language) <opcode_print_table,
op_print_tab>: Remove.
* m2-lang.c (m2_language::op_print_tab): Remove.
* language.h (struct language_defn) <post_parser, expression_ops,
opcode_print_table>: Remove.
* language.c (language_defn::expression_ops)
(auto_or_unknown_language::opcode_print_table): Remove.
* go-lang.h (class go_language) <opcode_print_table,
op_print_tab>: Remove.
* go-lang.c (go_language::op_print_tab): Remove.
* f-lang.h (class f_language) <opcode_print_table>: Remove
<op_print_tab>: Remove.
* f-lang.c (f_language::op_print_tab): Remove.
* expression.h (union exp_element): Remove.
(struct expression): Remove size_t parameter from constructor.
<resize>: Remove.
<first_opcode>: Update.
<nelts, elts>: Remove.
(EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): Remove.
(evaluate_subexp_standard, print_expression, op_string)
(dump_raw_expression): Don't declare.
* expprint.c (print_expression, print_subexp)
(print_subexp_funcall, print_subexp_standard, op_string)
(dump_raw_expression, dump_subexp, dump_subexp_body)
(dump_subexp_body_funcall, dump_subexp_body_standard): Remove.
(dump_prefix_expression): Update.
* eval.c (evaluate_subexp): Remove.
(evaluate_expression, evaluate_type): Update.
(evaluate_subexpression_type): Remove.
(fetch_subexp_value): Remove "pc" parameter. Update.
(extract_field_op, evaluate_struct_tuple, evaluate_funcall)
(evaluate_subexp_standard, evaluate_subexp_for_address)
(evaluate_subexp_with_coercion, evaluate_subexp_for_sizeof)
(evaluate_subexp_for_cast): Remove.
(parse_and_eval_type): Update.
* dtrace-probe.c (dtrace_probe::compile_to_ax): Update.
* d-lang.c (d_op_print_tab): Remove.
(class d_language) <opcode_print_table>: Remove.
* c-lang.h (c_op_print_tab): Don't declare.
* c-lang.c (c_op_print_tab): Remove.
(class c_language, class cplus_language, class asm_language, class
minimal_language) <opcode_print_table>: Remove.
* breakpoint.c (update_watchpoint, watchpoint_check)
(watchpoint_exp_is_const, watch_command_1): Update.
* ax-gdb.h (union exp_element): Don't declare.
* ax-gdb.c (const_var_ref, const_expr, maybe_const_expr)
(gen_repeat, gen_sizeof, gen_expr_for_cast, gen_expr)
(gen_expr_binop_rest): Remove.
(gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update.
* ada-lang.c (ada_op_print_tab): Remove.
(class ada_language) <post_parser, opcode_print_table>: Remove.
2021-03-08 Tom Tromey <tom@tromey.com>
* go-lang.c (go_language::expression_ops): Don't declare.

View file

@ -12652,43 +12652,6 @@ info_exceptions_command (const char *regexp, int from_tty)
printf_filtered ("%s: %s\n", info.name, paddress (gdbarch, info.addr));
}
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
static const struct op_print ada_op_print_tab[] = {
{":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
{"or else", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
{"and then", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
{"or", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
{"xor", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
{"and", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
{"=", BINOP_EQUAL, PREC_EQUAL, 0},
{"/=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
{"<=", BINOP_LEQ, PREC_ORDER, 0},
{">=", BINOP_GEQ, PREC_ORDER, 0},
{">", BINOP_GTR, PREC_ORDER, 0},
{"<", BINOP_LESS, PREC_ORDER, 0},
{">>", BINOP_RSH, PREC_SHIFT, 0},
{"<<", BINOP_LSH, PREC_SHIFT, 0},
{"+", BINOP_ADD, PREC_ADD, 0},
{"-", BINOP_SUB, PREC_ADD, 0},
{"&", BINOP_CONCAT, PREC_ADD, 0},
{"*", BINOP_MUL, PREC_MUL, 0},
{"/", BINOP_DIV, PREC_MUL, 0},
{"rem", BINOP_REM, PREC_MUL, 0},
{"mod", BINOP_MOD, PREC_MUL, 0},
{"**", BINOP_EXP, PREC_REPEAT, 0},
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
{"-", UNOP_NEG, PREC_PREFIX, 0},
{"+", UNOP_PLUS, PREC_PREFIX, 0},
{"not ", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
{"not ", UNOP_COMPLEMENT, PREC_PREFIX, 0},
{"abs ", UNOP_ABS, PREC_PREFIX, 0},
{".all", UNOP_IND, PREC_SUFFIX, 1},
{"'access", UNOP_ADDR, PREC_SUFFIX, 1},
{"'size", OP_ATR_SIZE, PREC_SUFFIX, 1},
{NULL, OP_NULL, PREC_SUFFIX, 0}
};
/* Language vector */
@ -13275,22 +13238,6 @@ public:
return ada_parse (ps);
}
/* See language.h.
Same as evaluate_type (*EXP), but resolves ambiguous symbol references
(marked by OP_VAR_VALUE nodes in which the symbol has an undefined
namespace) and converts operators that are user-defined into
appropriate function calls. If CONTEXT_TYPE is non-null, it provides
a preferred result type [at the moment, only type void has any
effect---causing procedures to be preferred over functions in calls].
A null CONTEXT_TYPE indicates that a non-void return type is
preferred. May change (expand) *EXP. */
void post_parser (expression_up *expp, struct parser_state *ps)
const override
{
}
/* See language.h. */
void emitchar (int ch, struct type *chtype,
@ -13353,11 +13300,6 @@ public:
const struct lang_varobj_ops *varobj_ops () const override
{ return &ada_varobj_ops; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return ada_op_print_tab; }
protected:
/* See language.h. */

View file

@ -70,14 +70,9 @@
/* Prototypes for local functions. */
/* There's a standard order to the arguments of these functions:
union exp_element ** --- pointer into expression
struct agent_expr * --- agent expression buffer to generate code into
struct axs_value * --- describes value left on top of stack */
static struct value *const_var_ref (struct symbol *var);
static struct value *const_expr (union exp_element **pc);
static struct value *maybe_const_expr (union exp_element **pc);
static void gen_traced_pop (struct agent_expr *, struct axs_value *);
static void gen_sign_extend (struct agent_expr *, struct type *);
@ -148,123 +143,13 @@ static void gen_struct_ref (struct agent_expr *ax,
const char *operand_name);
static void gen_static_field (struct agent_expr *ax, struct axs_value *value,
struct type *type, int fieldno);
static void gen_repeat (struct expression *exp, union exp_element **pc,
struct agent_expr *ax, struct axs_value *value);
static void gen_sizeof (struct expression *exp, union exp_element **pc,
struct agent_expr *ax, struct axs_value *value,
struct type *size_type);
static void gen_expr_binop_rest (struct expression *exp,
enum exp_opcode op, union exp_element **pc,
struct agent_expr *ax,
struct axs_value *value,
struct axs_value *value1,
struct axs_value *value2);
static void gen_expr_binop_rest (struct expression *exp,
enum exp_opcode op,
struct agent_expr *ax,
struct axs_value *value,
struct axs_value *value1,
struct axs_value *value2);
/* Detecting constant expressions. */
/* If the variable reference at *PC is a constant, return its value.
Otherwise, return zero.
Hey, Wally! How can a variable reference be a constant?
Well, Beav, this function really handles the OP_VAR_VALUE operator,
not specifically variable references. GDB uses OP_VAR_VALUE to
refer to any kind of symbolic reference: function names, enum
elements, and goto labels are all handled through the OP_VAR_VALUE
operator, even though they're constants. It makes sense given the
situation.
Gee, Wally, don'cha wonder sometimes if data representations that
subvert commonly accepted definitions of terms in favor of heavily
context-specific interpretations are really just a tool of the
programming hegemony to preserve their power and exclude the
proletariat? */
static struct value *
const_var_ref (struct symbol *var)
{
struct type *type = SYMBOL_TYPE (var);
switch (SYMBOL_CLASS (var))
{
case LOC_CONST:
return value_from_longest (type, (LONGEST) SYMBOL_VALUE (var));
case LOC_LABEL:
return value_from_pointer (type, (CORE_ADDR) SYMBOL_VALUE_ADDRESS (var));
default:
return 0;
}
}
/* If the expression starting at *PC has a constant value, return it.
Otherwise, return zero. If we return a value, then *PC will be
advanced to the end of it. If we return zero, *PC could be
anywhere. */
static struct value *
const_expr (union exp_element **pc)
{
enum exp_opcode op = (*pc)->opcode;
struct value *v1;
switch (op)
{
case OP_LONG:
{
struct type *type = (*pc)[1].type;
LONGEST k = (*pc)[2].longconst;
(*pc) += 4;
return value_from_longest (type, k);
}
case OP_VAR_VALUE:
{
struct value *v = const_var_ref ((*pc)[2].symbol);
(*pc) += 4;
return v;
}
/* We could add more operators in here. */
case UNOP_NEG:
(*pc)++;
v1 = const_expr (pc);
if (v1)
return value_neg (v1);
else
return 0;
default:
return 0;
}
}
/* Like const_expr, but guarantee also that *PC is undisturbed if the
expression is not constant. */
static struct value *
maybe_const_expr (union exp_element **pc)
{
union exp_element *tentative_pc = *pc;
struct value *v = const_expr (&tentative_pc);
/* If we got a value, then update the real PC. */
if (v)
*pc = tentative_pc;
return v;
}
/* Generating bytecode from GDB expressions: general assumptions */
@ -1691,592 +1576,8 @@ gen_aggregate_elt_ref (struct agent_expr *ax, struct axs_value *value,
return 0;
}
/* Generate code for GDB's magical `repeat' operator.
LVALUE @ INT creates an array INT elements long, and whose elements
have the same type as LVALUE, located in memory so that LVALUE is
its first element. For example, argv[0]@argc gives you the array
of command-line arguments.
Unfortunately, because we have to know the types before we actually
have a value for the expression, we can't implement this perfectly
without changing the type system, having values that occupy two
stack slots, doing weird things with sizeof, etc. So we require
the right operand to be a constant expression. */
static void
gen_repeat (struct expression *exp, union exp_element **pc,
struct agent_expr *ax, struct axs_value *value)
{
struct axs_value value1;
/* We don't want to turn this into an rvalue, so no conversions
here. */
gen_expr (exp, pc, ax, &value1);
if (value1.kind != axs_lvalue_memory)
error (_("Left operand of `@' must be an object in memory."));
/* Evaluate the length; it had better be a constant. */
{
struct value *v = const_expr (pc);
int length;
if (!v)
error (_("Right operand of `@' must be a "
"constant, in agent expressions."));
if (value_type (v)->code () != TYPE_CODE_INT)
error (_("Right operand of `@' must be an integer."));
length = value_as_long (v);
if (length <= 0)
error (_("Right operand of `@' must be positive."));
/* The top of the stack is already the address of the object, so
all we need to do is frob the type of the lvalue. */
{
/* FIXME-type-allocation: need a way to free this type when we are
done with it. */
struct type *array
= lookup_array_range_type (value1.type, 0, length - 1);
value->kind = axs_lvalue_memory;
value->type = array;
}
}
}
/* Emit code for the `sizeof' operator.
*PC should point at the start of the operand expression; we advance it
to the first instruction after the operand. */
static void
gen_sizeof (struct expression *exp, union exp_element **pc,
struct agent_expr *ax, struct axs_value *value,
struct type *size_type)
{
/* We don't care about the value of the operand expression; we only
care about its type. However, in the current arrangement, the
only way to find an expression's type is to generate code for it.
So we generate code for the operand, and then throw it away,
replacing it with code that simply pushes its size. */
int start = ax->len;
gen_expr (exp, pc, ax, value);
/* Throw away the code we just generated. */
ax->len = start;
ax_const_l (ax, TYPE_LENGTH (value->type));
value->kind = axs_rvalue;
value->type = size_type;
}
/* Generate bytecode for a cast to TO_TYPE. Advance *PC over the
subexpression. */
static void
gen_expr_for_cast (struct expression *exp, union exp_element **pc,
struct agent_expr *ax, struct axs_value *value,
struct type *to_type)
{
enum exp_opcode op = (*pc)[0].opcode;
/* Don't let symbols be handled with gen_expr because that throws an
"unknown type" error for no-debug data symbols. Instead, we want
the cast to reinterpret such symbols. */
if (op == OP_VAR_MSYM_VALUE || op == OP_VAR_VALUE)
{
if (op == OP_VAR_VALUE)
{
gen_var_ref (ax, value, (*pc)[2].symbol);
if (value->optimized_out)
error (_("`%s' has been optimized out, cannot use"),
(*pc)[2].symbol->print_name ());
}
else
gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile);
if (value->type->code () == TYPE_CODE_ERROR)
value->type = to_type;
(*pc) += 4;
}
else
gen_expr (exp, pc, ax, value);
gen_cast (ax, value, to_type);
}
/* Generating bytecode from GDB expressions: general recursive thingy */
/* XXX: i18n */
/* A gen_expr function written by a Gen-X'er guy.
Append code for the subexpression of EXPR starting at *POS_P to AX. */
void
gen_expr (struct expression *exp, union exp_element **pc,
struct agent_expr *ax, struct axs_value *value)
{
/* Used to hold the descriptions of operand expressions. */
struct axs_value value1, value2, value3;
enum exp_opcode op = (*pc)[0].opcode, op2;
int if1, go1, if2, go2, end;
struct type *int_type = builtin_type (ax->gdbarch)->builtin_int;
/* If we're looking at a constant expression, just push its value. */
{
struct value *v = maybe_const_expr (pc);
if (v)
{
ax_const_l (ax, value_as_long (v));
value->kind = axs_rvalue;
value->type = check_typedef (value_type (v));
return;
}
}
/* Otherwise, go ahead and generate code for it. */
switch (op)
{
/* Binary arithmetic operators. */
case BINOP_ADD:
case BINOP_SUB:
case BINOP_MUL:
case BINOP_DIV:
case BINOP_REM:
case BINOP_LSH:
case BINOP_RSH:
case BINOP_SUBSCRIPT:
case BINOP_BITWISE_AND:
case BINOP_BITWISE_IOR:
case BINOP_BITWISE_XOR:
case BINOP_EQUAL:
case BINOP_NOTEQUAL:
case BINOP_LESS:
case BINOP_GTR:
case BINOP_LEQ:
case BINOP_GEQ:
(*pc)++;
gen_expr (exp, pc, ax, &value1);
gen_usual_unary (ax, &value1);
gen_expr_binop_rest (exp, op, pc, ax, value, &value1, &value2);
break;
case BINOP_LOGICAL_AND:
(*pc)++;
/* Generate the obvious sequence of tests and jumps. */
gen_expr (exp, pc, ax, &value1);
gen_usual_unary (ax, &value1);
if1 = ax_goto (ax, aop_if_goto);
go1 = ax_goto (ax, aop_goto);
ax_label (ax, if1, ax->len);
gen_expr (exp, pc, ax, &value2);
gen_usual_unary (ax, &value2);
if2 = ax_goto (ax, aop_if_goto);
go2 = ax_goto (ax, aop_goto);
ax_label (ax, if2, ax->len);
ax_const_l (ax, 1);
end = ax_goto (ax, aop_goto);
ax_label (ax, go1, ax->len);
ax_label (ax, go2, ax->len);
ax_const_l (ax, 0);
ax_label (ax, end, ax->len);
value->kind = axs_rvalue;
value->type = int_type;
break;
case BINOP_LOGICAL_OR:
(*pc)++;
/* Generate the obvious sequence of tests and jumps. */
gen_expr (exp, pc, ax, &value1);
gen_usual_unary (ax, &value1);
if1 = ax_goto (ax, aop_if_goto);
gen_expr (exp, pc, ax, &value2);
gen_usual_unary (ax, &value2);
if2 = ax_goto (ax, aop_if_goto);
ax_const_l (ax, 0);
end = ax_goto (ax, aop_goto);
ax_label (ax, if1, ax->len);
ax_label (ax, if2, ax->len);
ax_const_l (ax, 1);
ax_label (ax, end, ax->len);
value->kind = axs_rvalue;
value->type = int_type;
break;
case TERNOP_COND:
(*pc)++;
gen_expr (exp, pc, ax, &value1);
gen_usual_unary (ax, &value1);
/* For (A ? B : C), it's easiest to generate subexpression
bytecodes in order, but if_goto jumps on true, so we invert
the sense of A. Then we can do B by dropping through, and
jump to do C. */
gen_logical_not (ax, &value1, int_type);
if1 = ax_goto (ax, aop_if_goto);
gen_expr (exp, pc, ax, &value2);
gen_usual_unary (ax, &value2);
end = ax_goto (ax, aop_goto);
ax_label (ax, if1, ax->len);
gen_expr (exp, pc, ax, &value3);
gen_usual_unary (ax, &value3);
ax_label (ax, end, ax->len);
/* This is arbitrary - what if B and C are incompatible types? */
value->type = value2.type;
value->kind = value2.kind;
break;
case BINOP_ASSIGN:
(*pc)++;
if ((*pc)[0].opcode == OP_INTERNALVAR)
{
const char *name = internalvar_name ((*pc)[1].internalvar);
struct trace_state_variable *tsv;
(*pc) += 3;
gen_expr (exp, pc, ax, value);
tsv = find_trace_state_variable (name);
if (tsv)
{
ax_tsv (ax, aop_setv, tsv->number);
if (ax->tracing)
ax_tsv (ax, aop_tracev, tsv->number);
}
else
error (_("$%s is not a trace state variable, "
"may not assign to it"), name);
}
else
error (_("May only assign to trace state variables"));
break;
case BINOP_ASSIGN_MODIFY:
(*pc)++;
op2 = (*pc)[0].opcode;
(*pc)++;
(*pc)++;
if ((*pc)[0].opcode == OP_INTERNALVAR)
{
const char *name = internalvar_name ((*pc)[1].internalvar);
struct trace_state_variable *tsv;
(*pc) += 3;
tsv = find_trace_state_variable (name);
if (tsv)
{
/* The tsv will be the left half of the binary operation. */
ax_tsv (ax, aop_getv, tsv->number);
if (ax->tracing)
ax_tsv (ax, aop_tracev, tsv->number);
/* Trace state variables are always 64-bit integers. */
value1.kind = axs_rvalue;
value1.type = builtin_type (ax->gdbarch)->builtin_long_long;
/* Now do right half of expression. */
gen_expr_binop_rest (exp, op2, pc, ax, value, &value1, &value2);
/* We have a result of the binary op, set the tsv. */
ax_tsv (ax, aop_setv, tsv->number);
if (ax->tracing)
ax_tsv (ax, aop_tracev, tsv->number);
}
else
error (_("$%s is not a trace state variable, "
"may not assign to it"), name);
}
else
error (_("May only assign to trace state variables"));
break;
/* Note that we need to be a little subtle about generating code
for comma. In C, we can do some optimizations here because
we know the left operand is only being evaluated for effect.
However, if the tracing kludge is in effect, then we always
need to evaluate the left hand side fully, so that all the
variables it mentions get traced. */
case BINOP_COMMA:
(*pc)++;
gen_expr (exp, pc, ax, &value1);
/* Don't just dispose of the left operand. We might be tracing,
in which case we want to emit code to trace it if it's an
lvalue. */
gen_traced_pop (ax, &value1);
gen_expr (exp, pc, ax, value);
/* It's the consumer's responsibility to trace the right operand. */
break;
case OP_LONG: /* some integer constant */
{
struct type *type = (*pc)[1].type;
LONGEST k = (*pc)[2].longconst;
(*pc) += 4;
gen_int_literal (ax, value, k, type);
}
break;
case OP_VAR_VALUE:
gen_var_ref (ax, value, (*pc)[2].symbol);
if (value->optimized_out)
error (_("`%s' has been optimized out, cannot use"),
(*pc)[2].symbol->print_name ());
if (value->type->code () == TYPE_CODE_ERROR)
error_unknown_type ((*pc)[2].symbol->print_name ());
(*pc) += 4;
break;
case OP_VAR_MSYM_VALUE:
gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile);
if (value->type->code () == TYPE_CODE_ERROR)
error_unknown_type ((*pc)[2].msymbol->linkage_name ());
(*pc) += 4;
break;
case OP_REGISTER:
{
const char *name = &(*pc)[2].string;
int reg;
(*pc) += 4 + BYTES_TO_EXP_ELEM ((*pc)[1].longconst + 1);
reg = user_reg_map_name_to_regnum (ax->gdbarch, name, strlen (name));
if (reg == -1)
internal_error (__FILE__, __LINE__,
_("Register $%s not available"), name);
/* No support for tracing user registers yet. */
if (reg >= gdbarch_num_cooked_regs (ax->gdbarch))
error (_("'%s' is a user-register; "
"GDB cannot yet trace user-register contents."),
name);
value->kind = axs_lvalue_register;
value->u.reg = reg;
value->type = register_type (ax->gdbarch, reg);
}
break;
case OP_INTERNALVAR:
{
struct internalvar *var = (*pc)[1].internalvar;
const char *name = internalvar_name (var);
struct trace_state_variable *tsv;
(*pc) += 3;
tsv = find_trace_state_variable (name);
if (tsv)
{
ax_tsv (ax, aop_getv, tsv->number);
if (ax->tracing)
ax_tsv (ax, aop_tracev, tsv->number);
/* Trace state variables are always 64-bit integers. */
value->kind = axs_rvalue;
value->type = builtin_type (ax->gdbarch)->builtin_long_long;
}
else if (! compile_internalvar_to_ax (var, ax, value))
error (_("$%s is not a trace state variable; GDB agent "
"expressions cannot use convenience variables."), name);
}
break;
/* Weirdo operator: see comments for gen_repeat for details. */
case BINOP_REPEAT:
/* Note that gen_repeat handles its own argument evaluation. */
(*pc)++;
gen_repeat (exp, pc, ax, value);
break;
case UNOP_CAST:
{
struct type *type = (*pc)[1].type;
(*pc) += 3;
gen_expr_for_cast (exp, pc, ax, value, type);
}
break;
case UNOP_CAST_TYPE:
{
int offset;
struct value *val;
struct type *type;
++*pc;
offset = *pc - exp->elts;
val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS);
type = value_type (val);
*pc = &exp->elts[offset];
gen_expr_for_cast (exp, pc, ax, value, type);
}
break;
case UNOP_MEMVAL:
{
struct type *type = check_typedef ((*pc)[1].type);
(*pc) += 3;
gen_expr (exp, pc, ax, value);
/* If we have an axs_rvalue or an axs_lvalue_memory, then we
already have the right value on the stack. For
axs_lvalue_register, we must convert. */
if (value->kind == axs_lvalue_register)
require_rvalue (ax, value);
value->type = type;
value->kind = axs_lvalue_memory;
}
break;
case UNOP_MEMVAL_TYPE:
{
int offset;
struct value *val;
struct type *type;
++*pc;
offset = *pc - exp->elts;
val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS);
type = value_type (val);
*pc = &exp->elts[offset];
gen_expr (exp, pc, ax, value);
/* If we have an axs_rvalue or an axs_lvalue_memory, then we
already have the right value on the stack. For
axs_lvalue_register, we must convert. */
if (value->kind == axs_lvalue_register)
require_rvalue (ax, value);
value->type = type;
value->kind = axs_lvalue_memory;
}
break;
case UNOP_PLUS:
(*pc)++;
/* + FOO is equivalent to 0 + FOO, which can be optimized. */
gen_expr (exp, pc, ax, value);
gen_usual_unary (ax, value);
break;
case UNOP_NEG:
(*pc)++;
/* -FOO is equivalent to 0 - FOO. */
gen_int_literal (ax, &value1, 0,
builtin_type (ax->gdbarch)->builtin_int);
gen_usual_unary (ax, &value1); /* shouldn't do much */
gen_expr (exp, pc, ax, &value2);
gen_usual_unary (ax, &value2);
gen_usual_arithmetic (ax, &value1, &value2);
gen_binop (ax, value, &value1, &value2, aop_sub, aop_sub, 1, "negation");
break;
case UNOP_LOGICAL_NOT:
(*pc)++;
gen_expr (exp, pc, ax, value);
gen_usual_unary (ax, value);
gen_logical_not (ax, value, int_type);
break;
case UNOP_COMPLEMENT:
(*pc)++;
gen_expr (exp, pc, ax, value);
gen_usual_unary (ax, value);
gen_integral_promotions (ax, value);
gen_complement (ax, value);
break;
case UNOP_IND:
(*pc)++;
gen_expr (exp, pc, ax, value);
gen_usual_unary (ax, value);
if (!pointer_type (value->type))
error (_("Argument of unary `*' is not a pointer."));
gen_deref (value);
break;
case UNOP_ADDR:
(*pc)++;
gen_expr (exp, pc, ax, value);
gen_address_of (value);
break;
case UNOP_SIZEOF:
(*pc)++;
/* Notice that gen_sizeof handles its own operand, unlike most
of the other unary operator functions. This is because we
have to throw away the code we generate. */
gen_sizeof (exp, pc, ax, value,
builtin_type (ax->gdbarch)->builtin_int);
break;
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
{
int length = (*pc)[1].longconst;
const char *name = &(*pc)[2].string;
(*pc) += 4 + BYTES_TO_EXP_ELEM (length + 1);
gen_expr (exp, pc, ax, value);
if (op == STRUCTOP_STRUCT)
gen_struct_ref (ax, value, name, ".", "structure or union");
else if (op == STRUCTOP_PTR)
gen_struct_ref (ax, value, name, "->",
"pointer to a structure or union");
else
/* If this `if' chain doesn't handle it, then the case list
shouldn't mention it, and we shouldn't be here. */
internal_error (__FILE__, __LINE__,
_("gen_expr: unhandled struct case"));
}
break;
case OP_THIS:
{
struct symbol *sym, *func;
const struct block *b;
const struct language_defn *lang;
b = block_for_pc (ax->scope);
func = block_linkage_function (b);
lang = language_def (func->language ());
sym = lookup_language_this (lang, b).symbol;
if (!sym)
error (_("no `%s' found"), lang->name_of_this ());
gen_var_ref (ax, value, sym);
if (value->optimized_out)
error (_("`%s' has been optimized out, cannot use"),
sym->print_name ());
(*pc) += 2;
}
break;
case OP_SCOPE:
{
struct type *type = (*pc)[1].type;
int length = longest_to_int ((*pc)[2].longconst);
const char *name = &(*pc)[3].string;
int found;
found = gen_aggregate_elt_ref (ax, value, type, name);
if (!found)
error (_("There is no field named %s"), name);
(*pc) += 5 + BYTES_TO_EXP_ELEM (length + 1);
}
break;
case OP_TYPE:
case OP_TYPEOF:
case OP_DECLTYPE:
error (_("Attempt to use a type name as an expression."));
default:
error (_("Unsupported operator %s (%d) in expression."),
op_name (op), op);
}
}
namespace expr
{
@ -2901,19 +2202,6 @@ gen_expr_binop_rest (struct expression *exp,
}
}
/* Variant of gen_expr_binop_rest that first generates the
right-hand-side. */
static void
gen_expr_binop_rest (struct expression *exp,
enum exp_opcode op, union exp_element **pc,
struct agent_expr *ax, struct axs_value *value,
struct axs_value *value1, struct axs_value *value2)
{
gen_expr (exp, pc, ax, value2);
gen_expr_binop_rest (exp, op, ax, value, value1, value2);
}
/* A helper function that emits a binop based on two operations. */
void
@ -3057,17 +2345,12 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr,
int trace_string)
{
agent_expr_up ax (new agent_expr (expr->gdbarch, scope));
union exp_element *pc;
struct axs_value value;
pc = expr->elts;
ax->tracing = 1;
ax->trace_string = trace_string;
value.optimized_out = 0;
if (expr->op != nullptr)
expr->op->generate_ax (expr, ax.get (), &value);
else
gen_expr (expr, &pc, ax.get (), &value);
expr->op->generate_ax (expr, ax.get (), &value);
/* Make sure we record the final object, and get rid of it. */
gen_traced_pop (ax.get (), &value);
@ -3089,16 +2372,11 @@ agent_expr_up
gen_eval_for_expr (CORE_ADDR scope, struct expression *expr)
{
agent_expr_up ax (new agent_expr (expr->gdbarch, scope));
union exp_element *pc;
struct axs_value value;
pc = expr->elts;
ax->tracing = 0;
value.optimized_out = 0;
if (expr->op != nullptr)
expr->op->generate_ax (expr, ax.get (), &value);
else
gen_expr (expr, &pc, ax.get (), &value);
expr->op->generate_ax (expr, ax.get (), &value);
require_rvalue (ax.get (), &value);
@ -3140,7 +2418,6 @@ gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch,
int nargs, struct expression **exprs)
{
agent_expr_up ax (new agent_expr (gdbarch, scope));
union exp_element *pc;
struct axs_value value;
int tem;
@ -3152,13 +2429,7 @@ gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch,
for (tem = nargs - 1; tem >= 0; --tem)
{
value.optimized_out = 0;
if (exprs[tem]->op != nullptr)
exprs[tem]->op->generate_ax (exprs[tem], ax.get (), &value);
else
{
pc = exprs[tem]->elts;
gen_expr (exprs[tem], &pc, ax.get (), &value);
}
exprs[tem]->op->generate_ax (exprs[tem], ax.get (), &value);
require_rvalue (ax.get (), &value);
}

View file

@ -22,7 +22,6 @@
#include "ax.h" /* For agent_expr_up. */
struct expression;
union exp_element;
/* Types and enums */

View file

@ -1898,12 +1898,11 @@ update_watchpoint (struct watchpoint *b, int reparse)
}
else if (within_current_scope && b->exp)
{
int pc = 0;
std::vector<value_ref_ptr> val_chain;
struct value *v, *result;
struct program_space *frame_pspace;
fetch_subexp_value (b->exp.get (), &pc, b->exp->op.get (), &v, &result,
fetch_subexp_value (b->exp.get (), b->exp->op.get (), &v, &result,
&val_chain, false);
/* Avoid setting b->val if it's already set. The meaning of
@ -5012,7 +5011,6 @@ watchpoint_check (bpstat bs)
free_all_values. We can't call free_all_values because we
might be in the middle of evaluating a function call. */
int pc = 0;
struct value *mark;
struct value *new_val;
@ -5023,7 +5021,7 @@ watchpoint_check (bpstat bs)
return WP_VALUE_CHANGED;
mark = value_mark ();
fetch_subexp_value (b->exp.get (), &pc, b->exp->op.get (), &new_val,
fetch_subexp_value (b->exp.get (), b->exp->op.get (), &new_val,
NULL, NULL, false);
if (b->val_bitsize != 0)
@ -10124,112 +10122,7 @@ break_range_command (const char *arg, int from_tty)
static bool
watchpoint_exp_is_const (const struct expression *exp)
{
if (exp->op != nullptr)
return exp->op->constant_p ();
int i = exp->nelts;
while (i > 0)
{
int oplenp, argsp;
/* We are only interested in the descriptor of each element. */
operator_length (exp, i, &oplenp, &argsp);
i -= oplenp;
switch (exp->elts[i].opcode)
{
case BINOP_ADD:
case BINOP_SUB:
case BINOP_MUL:
case BINOP_DIV:
case BINOP_REM:
case BINOP_MOD:
case BINOP_LSH:
case BINOP_RSH:
case BINOP_LOGICAL_AND:
case BINOP_LOGICAL_OR:
case BINOP_BITWISE_AND:
case BINOP_BITWISE_IOR:
case BINOP_BITWISE_XOR:
case BINOP_EQUAL:
case BINOP_NOTEQUAL:
case BINOP_LESS:
case BINOP_GTR:
case BINOP_LEQ:
case BINOP_GEQ:
case BINOP_REPEAT:
case BINOP_COMMA:
case BINOP_EXP:
case BINOP_MIN:
case BINOP_MAX:
case BINOP_INTDIV:
case BINOP_CONCAT:
case TERNOP_COND:
case TERNOP_SLICE:
case OP_LONG:
case OP_FLOAT:
case OP_LAST:
case OP_COMPLEX:
case OP_STRING:
case OP_ARRAY:
case OP_TYPE:
case OP_TYPEOF:
case OP_DECLTYPE:
case OP_TYPEID:
case OP_NAME:
case OP_OBJC_NSSTRING:
case UNOP_NEG:
case UNOP_LOGICAL_NOT:
case UNOP_COMPLEMENT:
case UNOP_ADDR:
case UNOP_HIGH:
case UNOP_CAST:
case UNOP_CAST_TYPE:
case UNOP_REINTERPRET_CAST:
case UNOP_DYNAMIC_CAST:
/* Unary, binary and ternary operators: We have to check
their operands. If they are constant, then so is the
result of that operation. For instance, if A and B are
determined to be constants, then so is "A + B".
UNOP_IND is one exception to the rule above, because the
value of *ADDR is not necessarily a constant, even when
ADDR is. */
break;
case OP_VAR_VALUE:
/* Check whether the associated symbol is a constant.
We use SYMBOL_CLASS rather than TYPE_CONST because it's
possible that a buggy compiler could mark a variable as
constant even when it is not, and TYPE_CONST would return
true in this case, while SYMBOL_CLASS wouldn't.
We also have to check for function symbols because they
are always constant. */
{
struct symbol *s = exp->elts[i + 2].symbol;
if (SYMBOL_CLASS (s) != LOC_BLOCK
&& SYMBOL_CLASS (s) != LOC_CONST
&& SYMBOL_CLASS (s) != LOC_CONST_BYTES)
return false;
break;
}
/* The default action is to return 0 because we are using
the optimistic approach here: If we don't know something,
then it is not a constant. */
default:
return false;
}
}
return true;
return exp->op->constant_p ();
}
/* Watchpoint destructor. */
@ -10730,7 +10623,6 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
const char *cond_end = NULL;
enum bptype bp_type;
int thread = -1;
int pc = 0;
/* Flag to indicate whether we are going to use masks for
the hardware watchpoint. */
bool use_mask = false;
@ -10847,8 +10739,8 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
exp_valid_block = tracker.block ();
struct value *mark = value_mark ();
struct value *val_as_value = nullptr;
fetch_subexp_value (exp.get (), &pc, exp->op.get (), &val_as_value, &result,
NULL, just_location);
fetch_subexp_value (exp.get (), exp->op.get (), &val_as_value, &result, NULL,
just_location);
if (val_as_value != NULL && just_location)
{

View file

@ -740,45 +740,6 @@ c_is_string_type_p (struct type *type)
return false;
}
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
const struct op_print c_op_print_tab[] =
{
{",", BINOP_COMMA, PREC_COMMA, 0},
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
{"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
{"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
{"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
{"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
{"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
{"==", BINOP_EQUAL, PREC_EQUAL, 0},
{"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
{"<=", BINOP_LEQ, PREC_ORDER, 0},
{">=", BINOP_GEQ, PREC_ORDER, 0},
{">", BINOP_GTR, PREC_ORDER, 0},
{"<", BINOP_LESS, PREC_ORDER, 0},
{">>", BINOP_RSH, PREC_SHIFT, 0},
{"<<", BINOP_LSH, PREC_SHIFT, 0},
{"+", BINOP_ADD, PREC_ADD, 0},
{"-", BINOP_SUB, PREC_ADD, 0},
{"*", BINOP_MUL, PREC_MUL, 0},
{"/", BINOP_DIV, PREC_MUL, 0},
{"%", BINOP_REM, PREC_MUL, 0},
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
{"+", UNOP_PLUS, PREC_PREFIX, 0},
{"-", UNOP_NEG, PREC_PREFIX, 0},
{"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
{"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
{"*", UNOP_IND, PREC_PREFIX, 0},
{"&", UNOP_ADDR, PREC_PREFIX, 0},
{"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
{"alignof ", UNOP_ALIGNOF, PREC_PREFIX, 0},
{"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
{"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
{NULL, OP_NULL, PREC_PREFIX, 0}
};
void
@ -886,11 +847,6 @@ public:
enum macro_expansion macro_expansion () const override
{ return macro_expansion_c; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return c_op_print_tab; }
};
/* Single instance of the C language class. */
@ -1065,11 +1021,6 @@ public:
const struct lang_varobj_ops *varobj_ops () const override
{ return &cplus_varobj_ops; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return c_op_print_tab; }
protected:
/* See language.h. */
@ -1140,11 +1091,6 @@ public:
enum macro_expansion macro_expansion () const override
{ return macro_expansion_c; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return c_op_print_tab; }
};
/* The single instance of the ASM language class. */
@ -1197,11 +1143,6 @@ public:
enum macro_expansion macro_expansion () const override
{ return macro_expansion_c; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return c_op_print_tab; }
};
/* The single instance of the minimal language class. */

View file

@ -106,8 +106,6 @@ extern void c_language_arch_info (struct gdbarch *gdbarch,
extern void c_emit_char (int c, struct type *type,
struct ui_file *stream, int quoter);
extern const struct op_print c_op_print_tab[];
/* These are in c-typeprint.c: */
extern void c_type_print_base (struct type *, struct ui_file *,

View file

@ -57,44 +57,6 @@ d_demangle (const char *symbol, int options)
return gdb_demangle (symbol, options | DMGL_DLANG);
}
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
static const struct op_print d_op_print_tab[] =
{
{",", BINOP_COMMA, PREC_COMMA, 0},
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
{"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
{"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
{"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
{"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
{"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
{"==", BINOP_EQUAL, PREC_ORDER, 0},
{"!=", BINOP_NOTEQUAL, PREC_ORDER, 0},
{"<=", BINOP_LEQ, PREC_ORDER, 0},
{">=", BINOP_GEQ, PREC_ORDER, 0},
{">", BINOP_GTR, PREC_ORDER, 0},
{"<", BINOP_LESS, PREC_ORDER, 0},
{">>", BINOP_RSH, PREC_SHIFT, 0},
{"<<", BINOP_LSH, PREC_SHIFT, 0},
{"+", BINOP_ADD, PREC_ADD, 0},
{"-", BINOP_SUB, PREC_ADD, 0},
{"~", BINOP_CONCAT, PREC_ADD, 0},
{"*", BINOP_MUL, PREC_MUL, 0},
{"/", BINOP_DIV, PREC_MUL, 0},
{"%", BINOP_REM, PREC_MUL, 0},
{"^^", BINOP_EXP, PREC_REPEAT, 0},
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
{"-", UNOP_NEG, PREC_PREFIX, 0},
{"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
{"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
{"*", UNOP_IND, PREC_PREFIX, 0},
{"&", UNOP_ADDR, PREC_PREFIX, 0},
{"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
{"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
{"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
{NULL, OP_NULL, PREC_PREFIX, 0}
};
/* Class representing the D language. */
class d_language : public language_defn
@ -216,11 +178,6 @@ public:
const char *name_of_this () const override
{ return "this"; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return d_op_print_tab; }
};
/* Single instance of the D language class. */

View file

@ -725,17 +725,9 @@ dtrace_probe::compile_to_ax (struct agent_expr *expr, struct axs_value *value,
unsigned n)
{
struct dtrace_probe_arg *arg;
union exp_element *pc;
arg = this->get_arg_by_number (n, expr->gdbarch);
if (arg->expr->op != nullptr)
arg->expr->op->generate_ax (arg->expr.get (), expr, value);
else
{
pc = arg->expr->elts;
gen_expr (arg->expr.get (), &pc, expr, value);
}
arg->expr->op->generate_ax (arg->expr.get (), expr, value);
require_rvalue (expr, value);
value->type = arg->type;

1624
gdb/eval.c

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -40,21 +40,6 @@ enum innermost_block_tracker_type
DEF_ENUM_FLAGS_TYPE (enum innermost_block_tracker_type,
innermost_block_tracker_types);
/* Definitions for saved C expressions. */
/* An expression is represented as a vector of union exp_element's.
Each exp_element is an opcode, except that some opcodes cause
the following exp_element to be treated as a long or double constant
or as a variable. The opcodes are obeyed, using a stack for temporaries.
The value is left on the temporary stack at the end. */
/* When it is necessary to include a string,
it can occupy as many exp_elements as it needs.
We find the length of the string using strlen,
divide to find out how many exp_elements are used up,
and skip that many. Strings, like numbers, are indicated
by the preceding opcode. */
enum exp_opcode : uint8_t
{
#define OP(name) name ,
@ -212,37 +197,17 @@ make_operation (Arg... args)
}
union exp_element
{
enum exp_opcode opcode;
struct symbol *symbol;
struct minimal_symbol *msymbol;
LONGEST longconst;
gdb_byte floatconst[16];
/* Really sizeof (union exp_element) characters (or less for the last
element of a string). */
char string;
struct type *type;
struct internalvar *internalvar;
const struct block *block;
struct objfile *objfile;
};
struct expression
{
expression (const struct language_defn *, struct gdbarch *, size_t);
expression (const struct language_defn *, struct gdbarch *);
~expression ();
DISABLE_COPY_AND_ASSIGN (expression);
void resize (size_t);
/* Return the opcode for the outermost sub-expression of this
expression. */
enum exp_opcode first_opcode () const
{
if (op != nullptr)
return op->opcode ();
return elts[0].opcode;
return op->opcode ();
}
/* Evaluate the expression. EXPECT_TYPE is the context type of the
@ -255,20 +220,10 @@ struct expression
/* Architecture it was parsed in. */
struct gdbarch *gdbarch;
expr::operation_up op;
int nelts = 0;
union exp_element *elts;
};
typedef std::unique_ptr<expression> expression_up;
/* Macros for converting between number of expression elements and bytes
to store that many expression elements. */
#define EXP_ELEM_TO_BYTES(elements) \
((elements) * sizeof (union exp_element))
#define BYTES_TO_EXP_ELEM(bytes) \
(((bytes) + sizeof (union exp_element) - 1) / sizeof (union exp_element))
/* From parse.c */
class innermost_block_tracker;
@ -289,9 +244,6 @@ extern expression_up parse_exp_1 (const char **, CORE_ADDR pc,
/* From eval.c */
extern struct value *evaluate_subexp_standard
(struct type *, struct expression *, int *, enum noside);
/* Evaluate a function call. The function to be called is in CALLEE and
the arguments passed to the function are in ARGVEC.
FUNCTION_NAME is the name of the function, if known.
@ -307,14 +259,8 @@ extern struct value *evaluate_subexp_do_call (expression *exp,
/* From expprint.c */
extern void print_expression (struct expression *, struct ui_file *);
extern const char *op_name (enum exp_opcode opcode);
extern const char *op_string (enum exp_opcode);
extern void dump_raw_expression (struct expression *,
struct ui_file *, const char *);
extern void dump_prefix_expression (struct expression *, struct ui_file *);
/* In an OP_RANGE expression, either bound could be empty, indicating

View file

@ -103,34 +103,6 @@ f_language::get_encoding (struct type *type)
/* Table of operators and their precedences for printing expressions. */
const struct op_print f_language::op_print_tab[] =
{
{"+", BINOP_ADD, PREC_ADD, 0},
{"+", UNOP_PLUS, PREC_PREFIX, 0},
{"-", BINOP_SUB, PREC_ADD, 0},
{"-", UNOP_NEG, PREC_PREFIX, 0},
{"*", BINOP_MUL, PREC_MUL, 0},
{"/", BINOP_DIV, PREC_MUL, 0},
{"DIV", BINOP_INTDIV, PREC_MUL, 0},
{"MOD", BINOP_REM, PREC_MUL, 0},
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
{".OR.", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
{".AND.", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
{".NOT.", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
{".EQ.", BINOP_EQUAL, PREC_EQUAL, 0},
{".NE.", BINOP_NOTEQUAL, PREC_EQUAL, 0},
{".LE.", BINOP_LEQ, PREC_ORDER, 0},
{".GE.", BINOP_GEQ, PREC_ORDER, 0},
{".GT.", BINOP_GTR, PREC_ORDER, 0},
{".LT.", BINOP_LESS, PREC_ORDER, 0},
{"**", UNOP_IND, PREC_PREFIX, 0},
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
{NULL, OP_NULL, PREC_REPEAT, 0}
};
/* A helper function for the "bound" intrinsics that checks that TYPE
is an array. LBOUND_P is true for lower bound; this is used for
the error message, if any. */

View file

@ -218,11 +218,6 @@ public:
enum array_ordering array_ordering () const override
{ return array_column_major; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return op_print_tab; }
protected:
/* See language.h. */
@ -231,10 +226,6 @@ protected:
(const lookup_name_info &lookup_name) const override;
private:
/* Table of opcode data for use by OPCODE_PRINT_TABLE member function. */
static const struct op_print op_print_tab[];
/* Return the encoding that should be used for the character type
TYPE. */

View file

@ -444,44 +444,6 @@ go_block_package_name (const struct block *block)
return NULL;
}
/* See go-lang.h.
TODO(dje): &^ ? */
const struct op_print go_language::op_print_tab[] =
{
{",", BINOP_COMMA, PREC_COMMA, 0},
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
{"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
{"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
{"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
{"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
{"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
{"==", BINOP_EQUAL, PREC_EQUAL, 0},
{"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
{"<=", BINOP_LEQ, PREC_ORDER, 0},
{">=", BINOP_GEQ, PREC_ORDER, 0},
{">", BINOP_GTR, PREC_ORDER, 0},
{"<", BINOP_LESS, PREC_ORDER, 0},
{">>", BINOP_RSH, PREC_SHIFT, 0},
{"<<", BINOP_LSH, PREC_SHIFT, 0},
{"+", BINOP_ADD, PREC_ADD, 0},
{"-", BINOP_SUB, PREC_ADD, 0},
{"*", BINOP_MUL, PREC_MUL, 0},
{"/", BINOP_DIV, PREC_MUL, 0},
{"%", BINOP_REM, PREC_MUL, 0},
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
{"-", UNOP_NEG, PREC_PREFIX, 0},
{"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
{"^", UNOP_COMPLEMENT, PREC_PREFIX, 0},
{"*", UNOP_IND, PREC_PREFIX, 0},
{"&", UNOP_ADDR, PREC_PREFIX, 0},
{"unsafe.Sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
{"++", UNOP_POSTINCREMENT, PREC_SUFFIX, 0},
{"--", UNOP_POSTDECREMENT, PREC_SUFFIX, 0},
{NULL, OP_NULL, PREC_SUFFIX, 0}
};
/* See language.h. */
void

View file

@ -134,18 +134,6 @@ public:
bool store_sym_names_in_linkage_form_p () const override
{ return true; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return op_print_tab; }
private:
/* Table of opcode data for use by OPCODE_PRINT_TABLE member function. */
static const struct op_print op_print_tab[];
};
#endif /* !defined (GO_LANG_H) */

View file

@ -774,14 +774,6 @@ language_defn::varobj_ops () const
return &c_varobj_ops;
}
/* See language.h. */
const struct exp_descriptor *
language_defn::expression_ops () const
{
return &exp_descriptor_standard;
}
/* Parent class for both the "auto" and "unknown" languages. These two
pseudo-languages are very similar so merging their implementations like
this makes sense. */
@ -901,18 +893,6 @@ public:
const char *name_of_this () const override
{ return "this"; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{
static const struct op_print unk_op_print_tab[] =
{
{NULL, OP_NULL, PREC_NULL, 0}
};
return unk_op_print_tab;
}
};
/* Class representing the fake "auto" language. */

View file

@ -515,17 +515,6 @@ struct language_defn
virtual int parser (struct parser_state *ps) const;
/* Given an expression *EXPP created by prefixifying the result of
la_parser, perform any remaining processing necessary to complete its
translation. *EXPP may change; la_post_parser is responsible for
releasing its previous contents, if necessary. */
virtual void post_parser (expression_up *expp, struct parser_state *ps)
const
{
/* By default the post-parser does nothing. */
}
/* Print the character CH (of type CHTYPE) on STREAM as part of the
contents of a literal string whose delimiter is QUOTER. */
@ -642,15 +631,6 @@ struct language_defn
virtual const struct lang_varobj_ops *varobj_ops () const;
/* Definitions related to expression printing, prefixifying, and
dumping. */
virtual const struct exp_descriptor *expression_ops () const;
/* Table for printing expressions. */
virtual const struct op_print *opcode_print_table () const = 0;
protected:
/* This is the overridable part of the GET_SYMBOL_NAME_MATCHER method.

View file

@ -113,43 +113,6 @@ eval_op_m2_subscript (struct type *expect_type, struct expression *exp,
/* Table of operators and their precedences for printing expressions. */
const struct op_print m2_language::op_print_tab[] =
{
{"+", BINOP_ADD, PREC_ADD, 0},
{"+", UNOP_PLUS, PREC_PREFIX, 0},
{"-", BINOP_SUB, PREC_ADD, 0},
{"-", UNOP_NEG, PREC_PREFIX, 0},
{"*", BINOP_MUL, PREC_MUL, 0},
{"/", BINOP_DIV, PREC_MUL, 0},
{"DIV", BINOP_INTDIV, PREC_MUL, 0},
{"MOD", BINOP_REM, PREC_MUL, 0},
{":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
{"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
{"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
{"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
{"=", BINOP_EQUAL, PREC_EQUAL, 0},
{"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
{"<=", BINOP_LEQ, PREC_ORDER, 0},
{">=", BINOP_GEQ, PREC_ORDER, 0},
{">", BINOP_GTR, PREC_ORDER, 0},
{"<", BINOP_LESS, PREC_ORDER, 0},
{"^", UNOP_IND, PREC_PREFIX, 0},
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
{"CAP", UNOP_CAP, PREC_BUILTIN_FUNCTION, 0},
{"CHR", UNOP_CHR, PREC_BUILTIN_FUNCTION, 0},
{"ORD", UNOP_ORD, PREC_BUILTIN_FUNCTION, 0},
{"FLOAT", UNOP_FLOAT, PREC_BUILTIN_FUNCTION, 0},
{"HIGH", UNOP_HIGH, PREC_BUILTIN_FUNCTION, 0},
{"MAX", UNOP_MAX, PREC_BUILTIN_FUNCTION, 0},
{"MIN", UNOP_MIN, PREC_BUILTIN_FUNCTION, 0},
{"ODD", UNOP_ODD, PREC_BUILTIN_FUNCTION, 0},
{"TRUNC", UNOP_TRUNC, PREC_BUILTIN_FUNCTION, 0},
{NULL, OP_NULL, PREC_BUILTIN_FUNCTION, 0}
};
/* Single instance of the M2 language. */
static m2_language m2_language_defn;

View file

@ -147,15 +147,6 @@ public:
bool range_checking_on_by_default () const override
{ return true; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return op_print_tab; }
private:
/* Table of opcode data for use by OPCODE_PRINT_TABLE member function. */
static const struct op_print op_print_tab[];
};
#endif /* M2_LANG_H */

View file

@ -282,44 +282,6 @@ objc_demangle (const char *mangled, int options)
return NULL; /* Not an objc mangled name. */
}
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
static const struct op_print objc_op_print_tab[] =
{
{",", BINOP_COMMA, PREC_COMMA, 0},
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
{"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
{"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
{"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
{"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
{"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
{"==", BINOP_EQUAL, PREC_EQUAL, 0},
{"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
{"<=", BINOP_LEQ, PREC_ORDER, 0},
{">=", BINOP_GEQ, PREC_ORDER, 0},
{">", BINOP_GTR, PREC_ORDER, 0},
{"<", BINOP_LESS, PREC_ORDER, 0},
{">>", BINOP_RSH, PREC_SHIFT, 0},
{"<<", BINOP_LSH, PREC_SHIFT, 0},
{"+", BINOP_ADD, PREC_ADD, 0},
{"-", BINOP_SUB, PREC_ADD, 0},
{"*", BINOP_MUL, PREC_MUL, 0},
{"/", BINOP_DIV, PREC_MUL, 0},
{"%", BINOP_REM, PREC_MUL, 0},
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
{"-", UNOP_NEG, PREC_PREFIX, 0},
{"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
{"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
{"*", UNOP_IND, PREC_PREFIX, 0},
{"&", UNOP_ADDR, PREC_PREFIX, 0},
{"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
{"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
{"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
{NULL, OP_NULL, PREC_NULL, 0}
};
/* Class representing the Objective-C language. */
class objc_language : public language_defn
@ -421,11 +383,6 @@ public:
enum macro_expansion macro_expansion () const override
{ return macro_expansion_c; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return objc_op_print_tab; }
};
/* Single instance of the class representing the Objective-C language. */

View file

@ -973,11 +973,6 @@ public:
enum macro_expansion macro_expansion () const override
{ return macro_expansion_c; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return c_op_print_tab; }
};
/* Single instance of the OpenCL language class. */

View file

@ -185,40 +185,6 @@ pascal_language::printchar (int c, struct type *type,
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
const struct op_print pascal_language::op_print_tab[] =
{
{",", BINOP_COMMA, PREC_COMMA, 0},
{":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
{"or", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
{"xor", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
{"and", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
{"=", BINOP_EQUAL, PREC_EQUAL, 0},
{"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
{"<=", BINOP_LEQ, PREC_ORDER, 0},
{">=", BINOP_GEQ, PREC_ORDER, 0},
{">", BINOP_GTR, PREC_ORDER, 0},
{"<", BINOP_LESS, PREC_ORDER, 0},
{"shr", BINOP_RSH, PREC_SHIFT, 0},
{"shl", BINOP_LSH, PREC_SHIFT, 0},
{"+", BINOP_ADD, PREC_ADD, 0},
{"-", BINOP_SUB, PREC_ADD, 0},
{"*", BINOP_MUL, PREC_MUL, 0},
{"/", BINOP_DIV, PREC_MUL, 0},
{"div", BINOP_INTDIV, PREC_MUL, 0},
{"mod", BINOP_REM, PREC_MUL, 0},
{"@", BINOP_REPEAT, PREC_REPEAT, 0},
{"-", UNOP_NEG, PREC_PREFIX, 0},
{"not", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
{"^", UNOP_IND, PREC_SUFFIX, 1},
{"@", UNOP_ADDR, PREC_PREFIX, 0},
{"sizeof", UNOP_SIZEOF, PREC_PREFIX, 0},
{NULL, OP_NULL, PREC_PREFIX, 0}
};
/* See language.h. */
void pascal_language::language_arch_info

View file

@ -154,17 +154,8 @@ public:
bool range_checking_on_by_default () const override
{ return true; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return op_print_tab; }
private:
/* Table of opcode data for use by OPCODE_PRINT_TABLE member function. */
static const struct op_print op_print_tab[];
/* Print the character C on STREAM as part of the contents of a literal
string. IN_QUOTES is reset to 0 if a char is written with #4 notation. */

File diff suppressed because it is too large Load diff

View file

@ -71,29 +71,15 @@ struct expr_builder
expout->op = std::move (op);
}
/* The size of the expression above. */
size_t expout_size;
/* The expression related to this parser state. */
expression_up expout;
/* The number of elements already in the expression. This is used
to know where to put new elements. */
size_t expout_ptr;
};
/* This is used for expression completion. */
struct expr_completion_state
{
/* The index of the last struct expression directly before a '.' or
'->'. This is set when parsing and is only used when completing a
field name. It is -1 if no dereference operation was found. */
int expout_last_struct = -1;
/* The last struct expression directly before a '.' or '->'. This
is set when parsing and is only used when completing a field
name. It is nullptr if no dereference operation was found. */
@ -157,11 +143,6 @@ struct parser_state : public expr_builder
return val;
}
/* Mark the current index as the starting location of a structure
expression. This is used when completing on field names. */
void mark_struct_expression ();
/* Mark the given operation as the starting location of a structure
expression. This is used when completing on field names. */
@ -376,173 +357,13 @@ struct objc_class_str
int theclass;
};
/* Reverse an expression from suffix form (in which it is constructed)
to prefix form (in which we can conveniently print or execute it).
Ordinarily this always returns -1. However, if LAST_STRUCT
is not -1 (i.e., we are trying to complete a field name), it will
return the index of the subexpression which is the left-hand-side
of the struct operation at LAST_STRUCT. */
extern int prefixify_expression (struct expression *expr,
int last_struct = -1);
extern void write_exp_elt_opcode (struct expr_builder *, enum exp_opcode);
extern void write_exp_elt_sym (struct expr_builder *, struct symbol *);
extern void write_exp_elt_longcst (struct expr_builder *, LONGEST);
extern void write_exp_elt_floatcst (struct expr_builder *, const gdb_byte *);
extern void write_exp_elt_type (struct expr_builder *, struct type *);
extern void write_exp_elt_intern (struct expr_builder *, struct internalvar *);
extern void write_exp_string (struct expr_builder *, struct stoken);
void write_exp_string_vector (struct expr_builder *, int type,
struct stoken_vector *vec);
extern void write_exp_bitstring (struct expr_builder *, struct stoken);
extern void write_exp_elt_block (struct expr_builder *, const struct block *);
extern void write_exp_elt_objfile (struct expr_builder *,
struct objfile *objfile);
extern void write_exp_msymbol (struct expr_builder *,
struct bound_minimal_symbol);
extern void write_dollar_variable (struct parser_state *, struct stoken str);
/* Write a reference to a symbol to the expression being built in PS.
NAME is the name of the symbol to write; SYM is the symbol. If SYM
is nullptr (meaning the 'symbol' member), a minimal symbol will be
searched for and used if available. Throws an exception if SYM is
nullptr and no minimal symbol can be found. */
extern void write_exp_symbol_reference (struct parser_state *ps,
const char *name,
struct block_symbol sym);
extern const char *find_template_name_end (const char *);
extern std::string copy_name (struct stoken);
extern int dump_subexp (struct expression *, struct ui_file *, int);
extern int dump_subexp_body_standard (struct expression *,
struct ui_file *, int);
/* Dump (to STREAM) a function call like expression at position ELT in the
expression array EXP. Return a new value for ELT just after the
function call expression. */
extern int dump_subexp_body_funcall (struct expression *exp,
struct ui_file *stream, int elt);
extern void operator_length (const struct expression *, int, int *, int *);
extern void operator_length_standard (const struct expression *, int, int *,
int *);
extern int operator_check_standard (struct expression *exp, int pos,
int (*objfile_func)
(struct objfile *objfile, void *data),
void *data);
extern bool parse_float (const char *p, int len,
const struct type *type, gdb_byte *data);
/* These codes indicate operator precedences for expression printing,
least tightly binding first. */
/* Adding 1 to a precedence value is done for binary operators,
on the operand which is more tightly bound, so that operators
of equal precedence within that operand will get parentheses. */
/* PREC_HYPER and PREC_ABOVE_COMMA are not the precedence of any operator;
they are used as the "surrounding precedence" to force
various kinds of things to be parenthesized. */
enum precedence
{
PREC_NULL, PREC_COMMA, PREC_ABOVE_COMMA, PREC_ASSIGN, PREC_LOGICAL_OR,
PREC_LOGICAL_AND, PREC_BITWISE_IOR, PREC_BITWISE_AND, PREC_BITWISE_XOR,
PREC_EQUAL, PREC_ORDER, PREC_SHIFT, PREC_ADD, PREC_MUL, PREC_REPEAT,
PREC_HYPER, PREC_PREFIX, PREC_SUFFIX, PREC_BUILTIN_FUNCTION
};
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
struct op_print
{
const char *string;
enum exp_opcode opcode;
/* Precedence of operator. These values are used only by comparisons. */
enum precedence precedence;
/* For a binary operator: 1 iff right associate.
For a unary operator: 1 iff postfix. */
int right_assoc;
};
/* Information needed to print, prefixify, and evaluate expressions for
a given language. */
struct exp_descriptor
{
/* Print subexpression. */
void (*print_subexp) (struct expression *, int *, struct ui_file *,
enum precedence);
/* Returns number of exp_elements needed to represent an operator and
the number of subexpressions it takes. */
void (*operator_length) (const struct expression*, int, int*, int *);
/* Call OBJFILE_FUNC for any objfile found being referenced by the
single operator of EXP at position POS. Operator parameters are
located at positive (POS + number) offsets in EXP. OBJFILE_FUNC
should never be called with NULL OBJFILE. OBJFILE_FUNC should
get passed an arbitrary caller supplied DATA pointer. If it
returns non-zero value then (any other) non-zero value should be
immediately returned to the caller. Otherwise zero should be
returned. */
int (*operator_check) (struct expression *exp, int pos,
int (*objfile_func) (struct objfile *objfile,
void *data),
void *data);
/* Dump the rest of this (prefix) expression after the operator
itself has been printed. See dump_subexp_body_standard in
(expprint.c). */
int (*dump_subexp_body) (struct expression *, struct ui_file *, int);
/* Evaluate an expression. */
struct value *(*evaluate_exp) (struct type *, struct expression *,
int *, enum noside);
};
/* Default descriptor containing standard definitions of all
elements. */
extern const struct exp_descriptor exp_descriptor_standard;
/* Functions used by language-specific extended operators to (recursively)
print/dump subexpressions. */
extern void print_subexp (struct expression *, int *, struct ui_file *,
enum precedence);
extern void print_subexp_standard (struct expression *, int *,
struct ui_file *, enum precedence);
/* Print a function call like expression to STREAM. This is called as a
helper function by which point the expression node identifying this as a
function call has already been stripped off and POS should point to the
number of function call arguments. EXP is the object containing the
list of expression elements. */
extern void print_subexp_funcall (struct expression *exp, int *pos,
struct ui_file *stream);
/* Function used to avoid direct calls to fprintf
in the code generated by the bison parser. */

View file

@ -2488,33 +2488,24 @@ ppc_linux_nat_target::check_condition (CORE_ADDR watch_addr,
struct expression *cond,
CORE_ADDR *data_value, int *len)
{
int pc = 1, num_accesses_left, num_accesses_right;
int num_accesses_left, num_accesses_right;
struct value *left_val, *right_val;
std::vector<value_ref_ptr> left_chain, right_chain;
if (cond->first_opcode () != BINOP_EQUAL)
expr::equal_operation *eqop
= dynamic_cast<expr::equal_operation *> (cond->op.get ());
if (eqop == nullptr)
return 0;
expr::operation *lhs = eqop->get_lhs ();
expr::operation *rhs = eqop->get_rhs ();
expr::operation *lhs = nullptr;
expr::operation *rhs = nullptr;
if (cond->op != nullptr)
{
expr::equal_operation *eqop
= dynamic_cast<expr::equal_operation *> (cond->op.get ());
if (eqop != nullptr)
{
lhs = eqop->get_lhs ();
rhs = eqop->get_rhs ();
}
}
fetch_subexp_value (cond, &pc, lhs, &left_val, NULL, &left_chain, false);
fetch_subexp_value (cond, lhs, &left_val, NULL, &left_chain, false);
num_accesses_left = num_memory_accesses (left_chain);
if (left_val == NULL || num_accesses_left < 0)
return 0;
fetch_subexp_value (cond, &pc, rhs, &right_val, NULL, &right_chain, false);
fetch_subexp_value (cond, rhs, &right_val, NULL, &right_chain, false);
num_accesses_right = num_memory_accesses (right_chain);
if (right_val == NULL || num_accesses_right < 0)

View file

@ -1375,14 +1375,8 @@ set_command (const char *exp, int from_tty)
{
expression_up expr = parse_expression (exp);
enum exp_opcode opcode = OP_NULL;
if (expr->op != nullptr)
opcode = expr->op->opcode ();
else if (expr->nelts >= 1)
opcode = expr->elts[0].opcode;
if (opcode != OP_NULL)
switch (opcode)
switch (expr->op->opcode ())
{
case UNOP_PREINCREMENT:
case UNOP_POSTINCREMENT:

View file

@ -209,11 +209,6 @@ public:
bool range_checking_on_by_default () const override
{ return true; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return c_op_print_tab; }
private:
/* Helper for value_print_inner, arguments are as for that function.

View file

@ -1441,15 +1441,10 @@ stap_probe::compile_to_ax (struct agent_expr *expr, struct axs_value *value,
unsigned n)
{
struct stap_probe_arg *arg;
union exp_element *pc;
arg = this->get_arg_by_number (n, expr->gdbarch);
pc = arg->aexpr->elts;
if (arg->aexpr->op != nullptr)
arg->aexpr->op->generate_ax (arg->aexpr.get (), expr, value);
else
gen_expr (arg->aexpr.get (), &pc, expr, value);
arg->aexpr->op->generate_ax (arg->aexpr.get (), expr, value);
require_rvalue (expr, value);
value->type = arg->atype;

View file

@ -691,15 +691,10 @@ validate_actionline (const char *line, struct breakpoint *b)
if (exp->first_opcode () == OP_VAR_VALUE)
{
symbol *sym;
if (exp->op != nullptr)
{
expr::var_value_operation *vvop
= (dynamic_cast<expr::var_value_operation *>
(exp->op.get ()));
sym = vvop->get_symbol ();
}
else
sym = exp->elts[2].symbol;
expr::var_value_operation *vvop
= (dynamic_cast<expr::var_value_operation *>
(exp->op.get ()));
sym = vvop->get_symbol ();
if (SYMBOL_CLASS (sym) == LOC_CONST)
{
@ -1395,16 +1390,10 @@ encode_actions_1 (struct command_line *action,
{
case OP_REGISTER:
{
const char *name;
if (exp->op != nullptr)
{
expr::register_operation *regop
= (dynamic_cast<expr::register_operation *>
(exp->op.get ()));
name = regop->get_name ();
}
else
name = &exp->elts[2].string;
expr::register_operation *regop
= (dynamic_cast<expr::register_operation *>
(exp->op.get ()));
const char *name = regop->get_name ();
i = user_reg_map_name_to_regnum (target_gdbarch (),
name, strlen (name));
@ -1424,16 +1413,10 @@ encode_actions_1 (struct command_line *action,
/* Safe because we know it's a simple expression. */
tempval = evaluate_expression (exp.get ());
addr = value_address (tempval);
struct type *type;
if (exp->op != nullptr)
{
expr::unop_memval_operation *memop
= (dynamic_cast<expr::unop_memval_operation *>
(exp->op.get ()));
type = memop->get_type ();
}
else
type = exp->elts[1].type;
expr::unop_memval_operation *memop
= (dynamic_cast<expr::unop_memval_operation *>
(exp->op.get ()));
struct type *type = memop->get_type ();
/* Initialize the TYPE_LENGTH if it is a typedef. */
check_typedef (type);
collect->add_memrange (target_gdbarch (),
@ -1447,17 +1430,10 @@ encode_actions_1 (struct command_line *action,
case OP_VAR_VALUE:
{
struct symbol *sym;
if (exp->op != nullptr)
{
expr::var_value_operation *vvo
= (dynamic_cast<expr::var_value_operation *>
(exp->op.get ()));
sym = vvo->get_symbol ();
}
else
sym = exp->elts[2].symbol;
expr::var_value_operation *vvo
= (dynamic_cast<expr::var_value_operation *>
(exp->op.get ()));
struct symbol *sym = vvo->get_symbol ();
const char *name = sym->natural_name ();
collect->collect_symbol (sym,

View file

@ -2015,29 +2015,19 @@ init_if_undefined_command (const char* args, int from_tty)
/* Validate the expression.
Was the expression an assignment?
Or even an expression at all? */
if ((expr->nelts == 0 && expr->op == nullptr)
|| expr->first_opcode () != BINOP_ASSIGN)
if (expr->op == nullptr || expr->first_opcode () != BINOP_ASSIGN)
error (_("Init-if-undefined requires an assignment expression."));
/* Extract the variable from the parsed expression.
In the case of an assign the lvalue will be in elts[1] and elts[2]. */
if (expr->op == nullptr)
/* Extract the variable from the parsed expression. */
expr::assign_operation *assign
= dynamic_cast<expr::assign_operation *> (expr->op.get ());
if (assign != nullptr)
{
if (expr->elts[1].opcode == OP_INTERNALVAR)
intvar = expr->elts[2].internalvar;
}
else
{
expr::assign_operation *assign
= dynamic_cast<expr::assign_operation *> (expr->op.get ());
if (assign != nullptr)
{
expr::operation *lhs = assign->get_lhs ();
expr::internalvar_operation *ivarop
= dynamic_cast<expr::internalvar_operation *> (lhs);
if (ivarop != nullptr)
intvar = ivarop->get_internalvar ();
}
expr::operation *lhs = assign->get_lhs ();
expr::internalvar_operation *ivarop
= dynamic_cast<expr::internalvar_operation *> (lhs);
if (ivarop != nullptr)
intvar = ivarop->get_internalvar ();
}
if (intvar == nullptr)

View file

@ -914,13 +914,6 @@ extern struct value *evaluate_expression (struct expression *exp,
extern struct value *evaluate_type (struct expression *exp);
extern struct value *evaluate_subexp (struct type *expect_type,
struct expression *exp,
int *pos, enum noside noside);
extern struct value *evaluate_subexpression_type (struct expression *exp,
int subexp);
extern value *evaluate_var_value (enum noside noside, const block *blk,
symbol *var);
@ -931,17 +924,12 @@ extern value *evaluate_var_msym_value (enum noside noside,
extern value *eval_skip_value (expression *exp);
namespace expr { class operation; };
extern void fetch_subexp_value (struct expression *exp, int *pc,
extern void fetch_subexp_value (struct expression *exp,
expr::operation *op,
struct value **valp, struct value **resultp,
std::vector<value_ref_ptr> *val_chain,
bool preserve_errors);
extern const char *extract_field_op (struct expression *exp, int *subexp);
extern struct value *evaluate_subexp_with_coercion (struct expression *,
int *, enum noside);
extern struct value *parse_and_eval (const char *exp);
extern struct value *parse_to_comma_and_eval (const char **expp);