diff options
author | Tom Tromey <tom@tromey.com> | 2021-03-08 07:27:57 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2021-03-08 07:28:41 -0700 |
commit | 1eaebe02cfe78229d78ac27f5bd6651e1c1af863 (patch) | |
tree | 870c2965ac8dada5ed4527853f829c3ddbbaf5a2 /gdb | |
parent | f2a98603a807101722f12b8d7a1aca9651deb133 (diff) | |
download | gdb-1eaebe02cfe78229d78ac27f5bd6651e1c1af863.zip gdb-1eaebe02cfe78229d78ac27f5bd6651e1c1af863.tar.gz gdb-1eaebe02cfe78229d78ac27f5bd6651e1c1af863.tar.bz2 |
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.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 72 | ||||
-rw-r--r-- | gdb/ada-lang.c | 58 | ||||
-rw-r--r-- | gdb/ax-gdb.c | 735 | ||||
-rw-r--r-- | gdb/ax-gdb.h | 1 | ||||
-rw-r--r-- | gdb/breakpoint.c | 118 | ||||
-rw-r--r-- | gdb/c-lang.c | 59 | ||||
-rw-r--r-- | gdb/c-lang.h | 2 | ||||
-rw-r--r-- | gdb/d-lang.c | 43 | ||||
-rw-r--r-- | gdb/dtrace-probe.c | 10 | ||||
-rw-r--r-- | gdb/eval.c | 1624 | ||||
-rw-r--r-- | gdb/expprint.c | 1117 | ||||
-rw-r--r-- | gdb/expression.h | 58 | ||||
-rw-r--r-- | gdb/f-lang.c | 28 | ||||
-rw-r--r-- | gdb/f-lang.h | 9 | ||||
-rw-r--r-- | gdb/go-lang.c | 38 | ||||
-rw-r--r-- | gdb/go-lang.h | 12 | ||||
-rw-r--r-- | gdb/language.c | 20 | ||||
-rw-r--r-- | gdb/language.h | 20 | ||||
-rw-r--r-- | gdb/m2-lang.c | 37 | ||||
-rw-r--r-- | gdb/m2-lang.h | 9 | ||||
-rw-r--r-- | gdb/objc-lang.c | 43 | ||||
-rw-r--r-- | gdb/opencl-lang.c | 5 | ||||
-rw-r--r-- | gdb/p-lang.c | 34 | ||||
-rw-r--r-- | gdb/p-lang.h | 9 | ||||
-rw-r--r-- | gdb/parse.c | 978 | ||||
-rw-r--r-- | gdb/parser-defs.h | 179 | ||||
-rw-r--r-- | gdb/ppc-linux-nat.c | 25 | ||||
-rw-r--r-- | gdb/printcmd.c | 8 | ||||
-rw-r--r-- | gdb/rust-lang.h | 5 | ||||
-rw-r--r-- | gdb/stap-probe.c | 7 | ||||
-rw-r--r-- | gdb/tracepoint.c | 56 | ||||
-rw-r--r-- | gdb/value.c | 30 | ||||
-rw-r--r-- | gdb/value.h | 14 |
33 files changed, 147 insertions, 5316 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 630679a..c9328de 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,77 @@ 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. * go-lang.h (class go_language) <expression_ops>: Remove. * opencl-lang.c (evaluate_subexp_opencl, exp_descriptor_opencl): diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index cfc2a6f..db7eba3 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -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. */ diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index d2f50bb..788be52 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -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); } diff --git a/gdb/ax-gdb.h b/gdb/ax-gdb.h index 5b7a513..b143847 100644 --- a/gdb/ax-gdb.h +++ b/gdb/ax-gdb.h @@ -22,7 +22,6 @@ #include "ax.h" /* For agent_expr_up. */ struct expression; -union exp_element; /* Types and enums */ diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index aa2abce..de1e79b 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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) { diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 00ab941..1ad7ea2 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -741,45 +741,6 @@ c_is_string_type_p (struct type *type) } -/* 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 c_language_arch_info (struct gdbarch *gdbarch, @@ -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. */ diff --git a/gdb/c-lang.h b/gdb/c-lang.h index 543a626..b35e8b1 100644 --- a/gdb/c-lang.h +++ b/gdb/c-lang.h @@ -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 *, diff --git a/gdb/d-lang.c b/gdb/d-lang.c index 4488c10..6c9b730 100644 --- a/gdb/d-lang.c +++ b/gdb/d-lang.c @@ -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. */ diff --git a/gdb/dtrace-probe.c b/gdb/dtrace-probe.c index 3fa02dd..cccd3a8 100644 --- a/gdb/dtrace-probe.c +++ b/gdb/dtrace-probe.c @@ -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; @@ -43,29 +43,6 @@ #include "expop.h" #include "c-exp.h" -/* Prototypes for local functions. */ - -static struct value *evaluate_subexp_for_sizeof (struct expression *, int *, - enum noside); - -static struct value *evaluate_subexp_for_address (struct expression *, - int *, enum noside); - -static value *evaluate_subexp_for_cast (expression *exp, int *pos, - enum noside noside, - struct type *type); - -static struct value *evaluate_struct_tuple (struct value *, - struct expression *, int *, - enum noside, int); - -struct value * -evaluate_subexp (struct type *expect_type, struct expression *exp, - int *pos, enum noside noside) -{ - return ((*exp->language_defn->expression_ops ()->evaluate_exp) - (expect_type, exp, pos, noside)); -} /* Parse the string EXP as a C expression, evaluate it, and return the result as a number. */ @@ -120,14 +97,7 @@ expression::evaluate (struct type *expect_type, enum noside noside) && !thread_stack_temporaries_enabled_p (inferior_thread ())) stack_temporaries.emplace (inferior_thread ()); - struct value *retval; - if (op != nullptr) - retval = op->evaluate (expect_type, this, noside); - else - { - int pos = 0; - retval = evaluate_subexp (expect_type, this, &pos, noside); - } + struct value *retval = op->evaluate (expect_type, this, noside); if (stack_temporaries.has_value () && value_in_thread_stack_temporaries (retval, inferior_thread ())) @@ -153,17 +123,6 @@ evaluate_type (struct expression *exp) return exp->evaluate (nullptr, EVAL_AVOID_SIDE_EFFECTS); } -/* Evaluate a subexpression, avoiding all memory references and - getting a value whose type alone is correct. */ - -struct value * -evaluate_subexpression_type (struct expression *exp, int subexp) -{ - if (exp->op != nullptr) - return exp->op->evaluate (nullptr, exp, EVAL_AVOID_SIDE_EFFECTS); - return evaluate_subexp (nullptr, exp, &subexp, EVAL_AVOID_SIDE_EFFECTS); -} - /* Find the current value of a watchpoint on EXP. Return the value in *VALP and *RESULTP and the chain of intermediate and final values in *VAL_CHAIN. RESULTP and VAL_CHAIN may be NULL if the caller does @@ -187,7 +146,7 @@ evaluate_subexpression_type (struct expression *exp, int subexp) values will be left on the value chain. */ void -fetch_subexp_value (struct expression *exp, int *pc, +fetch_subexp_value (struct expression *exp, expr::operation *op, struct value **valp, struct value **resultp, std::vector<value_ref_ptr> *val_chain, @@ -207,10 +166,7 @@ fetch_subexp_value (struct expression *exp, int *pc, try { - if (op == nullptr) - result = evaluate_subexp (nullptr, exp, pc, EVAL_NORMAL); - else - result = op->evaluate (nullptr, exp, EVAL_NORMAL); + result = op->evaluate (nullptr, exp, EVAL_NORMAL); } catch (const gdb_exception &ex) { @@ -263,91 +219,6 @@ fetch_subexp_value (struct expression *exp, int *pc, } } -/* Extract a field operation from an expression. If the subexpression - of EXP starting at *SUBEXP is not a structure dereference - operation, return NULL. Otherwise, return the name of the - dereferenced field, and advance *SUBEXP to point to the - subexpression of the left-hand-side of the dereference. This is - used when completing field names. */ - -const char * -extract_field_op (struct expression *exp, int *subexp) -{ - int tem; - char *result; - - if (exp->elts[*subexp].opcode != STRUCTOP_STRUCT - && exp->elts[*subexp].opcode != STRUCTOP_PTR) - return NULL; - tem = longest_to_int (exp->elts[*subexp + 1].longconst); - result = &exp->elts[*subexp + 2].string; - (*subexp) += 1 + 3 + BYTES_TO_EXP_ELEM (tem + 1); - return result; -} - -/* This function evaluates brace-initializers (in C/C++) for - structure types. */ - -static struct value * -evaluate_struct_tuple (struct value *struct_val, - struct expression *exp, - int *pos, enum noside noside, int nargs) -{ - struct type *struct_type = check_typedef (value_type (struct_val)); - struct type *field_type; - int fieldno = -1; - - while (--nargs >= 0) - { - struct value *val = NULL; - int bitpos, bitsize; - bfd_byte *addr; - - fieldno++; - /* Skip static fields. */ - while (fieldno < struct_type->num_fields () - && field_is_static (&struct_type->field (fieldno))) - fieldno++; - if (fieldno >= struct_type->num_fields ()) - error (_("too many initializers")); - field_type = struct_type->field (fieldno).type (); - if (field_type->code () == TYPE_CODE_UNION - && TYPE_FIELD_NAME (struct_type, fieldno)[0] == '0') - error (_("don't know which variant you want to set")); - - /* Here, struct_type is the type of the inner struct, - while substruct_type is the type of the inner struct. - These are the same for normal structures, but a variant struct - contains anonymous union fields that contain substruct fields. - The value fieldno is the index of the top-level (normal or - anonymous union) field in struct_field, while the value - subfieldno is the index of the actual real (named inner) field - in substruct_type. */ - - field_type = struct_type->field (fieldno).type (); - if (val == 0) - val = evaluate_subexp (field_type, exp, pos, noside); - - /* Now actually set the field in struct_val. */ - - /* Assign val to field fieldno. */ - if (value_type (val) != field_type) - val = value_cast (field_type, val); - - bitsize = TYPE_FIELD_BITSIZE (struct_type, fieldno); - bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno); - addr = value_contents_writeable (struct_val) + bitpos / 8; - if (bitsize) - modify_field (struct_type, addr, - value_as_long (val), bitpos % 8, bitsize); - else - memcpy (addr, value_contents (val), - TYPE_LENGTH (value_type (val))); - - } - return struct_val; -} - /* Promote value ARG1 as appropriate before performing a unary operation on this argument. If the result is not appropriate for any particular language then it @@ -811,412 +682,6 @@ evaluate_subexp_do_call (expression *exp, enum noside noside, } } -/* Helper for evaluating an OP_FUNCALL. */ - -static value * -evaluate_funcall (type *expect_type, expression *exp, int *pos, - enum noside noside) -{ - int tem; - int pc2 = 0; - value *arg1 = NULL; - value *arg2 = NULL; - int save_pos1; - symbol *function = NULL; - char *function_name = NULL; - const char *var_func_name = NULL; - - int pc = (*pos); - (*pos) += 2; - - exp_opcode op = exp->elts[*pos].opcode; - int nargs = longest_to_int (exp->elts[pc].longconst); - /* Allocate arg vector, including space for the function to be - called in argvec[0], a potential `this', and a terminating - NULL. */ - value **argvec = (value **) alloca (sizeof (value *) * (nargs + 3)); - if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) - { - /* First, evaluate the structure into arg2. */ - pc2 = (*pos)++; - - if (op == STRUCTOP_MEMBER) - { - arg2 = evaluate_subexp_for_address (exp, pos, noside); - } - else - { - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - } - - /* If the function is a virtual function, then the aggregate - value (providing the structure) plays its part by providing - the vtable. Otherwise, it is just along for the ride: call - the function directly. */ - - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - - type *a1_type = check_typedef (value_type (arg1)); - if (noside == EVAL_SKIP) - tem = 1; /* Set it to the right arg index so that all - arguments can also be skipped. */ - else if (a1_type->code () == TYPE_CODE_METHODPTR) - { - if (noside == EVAL_AVOID_SIDE_EFFECTS) - arg1 = value_zero (TYPE_TARGET_TYPE (a1_type), not_lval); - else - arg1 = cplus_method_ptr_to_value (&arg2, arg1); - - /* Now, say which argument to start evaluating from. */ - nargs++; - tem = 2; - argvec[1] = arg2; - } - else if (a1_type->code () == TYPE_CODE_MEMBERPTR) - { - struct type *type_ptr - = lookup_pointer_type (TYPE_SELF_TYPE (a1_type)); - struct type *target_type_ptr - = lookup_pointer_type (TYPE_TARGET_TYPE (a1_type)); - - /* Now, convert these values to an address. */ - arg2 = value_cast (type_ptr, arg2); - - long mem_offset = value_as_long (arg1); - - arg1 = value_from_pointer (target_type_ptr, - value_as_long (arg2) + mem_offset); - arg1 = value_ind (arg1); - tem = 1; - } - else - error (_("Non-pointer-to-member value used in pointer-to-member " - "construct")); - } - else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) - { - /* Hair for method invocations. */ - int tem2; - - nargs++; - /* First, evaluate the structure into arg2. */ - pc2 = (*pos)++; - tem2 = longest_to_int (exp->elts[pc2 + 1].longconst); - *pos += 3 + BYTES_TO_EXP_ELEM (tem2 + 1); - - if (op == STRUCTOP_STRUCT) - { - /* If v is a variable in a register, and the user types - v.method (), this will produce an error, because v has no - address. - - A possible way around this would be to allocate a copy of - the variable on the stack, copy in the contents, call the - function, and copy out the contents. I.e. convert this - from call by reference to call by copy-return (or - whatever it's called). However, this does not work - because it is not the same: the method being called could - stash a copy of the address, and then future uses through - that address (after the method returns) would be expected - to use the variable itself, not some copy of it. */ - arg2 = evaluate_subexp_for_address (exp, pos, noside); - } - else - { - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - - /* Check to see if the operator '->' has been overloaded. - If the operator has been overloaded replace arg2 with the - value returned by the custom operator and continue - evaluation. */ - while (unop_user_defined_p (op, arg2)) - { - struct value *value = NULL; - try - { - value = value_x_unop (arg2, op, noside); - } - - catch (const gdb_exception_error &except) - { - if (except.error == NOT_FOUND_ERROR) - break; - else - throw; - } - - arg2 = value; - } - } - /* Now, say which argument to start evaluating from. */ - tem = 2; - } - else if (op == OP_SCOPE - && overload_resolution - && (exp->language_defn->la_language == language_cplus)) - { - /* Unpack it locally so we can properly handle overload - resolution. */ - char *name; - int local_tem; - - pc2 = (*pos)++; - local_tem = longest_to_int (exp->elts[pc2 + 2].longconst); - (*pos) += 4 + BYTES_TO_EXP_ELEM (local_tem + 1); - struct type *type = exp->elts[pc2 + 1].type; - name = &exp->elts[pc2 + 3].string; - - function = NULL; - function_name = NULL; - if (type->code () == TYPE_CODE_NAMESPACE) - { - function = cp_lookup_symbol_namespace (type->name (), - name, - get_selected_block (0), - VAR_DOMAIN).symbol; - if (function == NULL) - error (_("No symbol \"%s\" in namespace \"%s\"."), - name, type->name ()); - - tem = 1; - /* arg2 is left as NULL on purpose. */ - } - else - { - gdb_assert (type->code () == TYPE_CODE_STRUCT - || type->code () == TYPE_CODE_UNION); - function_name = name; - - /* We need a properly typed value for method lookup. For - static methods arg2 is otherwise unused. */ - arg2 = value_zero (type, lval_memory); - ++nargs; - tem = 2; - } - } - else if (op == OP_ADL_FUNC) - { - /* Save the function position and move pos so that the arguments - can be evaluated. */ - int func_name_len; - - save_pos1 = *pos; - tem = 1; - - func_name_len = longest_to_int (exp->elts[save_pos1 + 3].longconst); - (*pos) += 6 + BYTES_TO_EXP_ELEM (func_name_len + 1); - } - else - { - /* Non-method function call. */ - save_pos1 = *pos; - tem = 1; - - /* If this is a C++ function wait until overload resolution. */ - if (op == OP_VAR_VALUE - && overload_resolution - && (exp->language_defn->la_language == language_cplus)) - { - (*pos) += 4; /* Skip the evaluation of the symbol. */ - argvec[0] = NULL; - } - else - { - if (op == OP_VAR_MSYM_VALUE) - { - minimal_symbol *msym = exp->elts[*pos + 2].msymbol; - var_func_name = msym->print_name (); - } - else if (op == OP_VAR_VALUE) - { - symbol *sym = exp->elts[*pos + 2].symbol; - var_func_name = sym->print_name (); - } - - argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside); - type *type = value_type (argvec[0]); - if (type && type->code () == TYPE_CODE_PTR) - type = TYPE_TARGET_TYPE (type); - if (type && type->code () == TYPE_CODE_FUNC) - { - for (; tem <= nargs && tem <= type->num_fields (); tem++) - { - argvec[tem] = evaluate_subexp (type->field (tem - 1).type (), - exp, pos, noside); - } - } - } - } - - /* Evaluate arguments (if not already done, e.g., namespace::func() - and overload-resolution is off). */ - for (; tem <= nargs; tem++) - { - /* Ensure that array expressions are coerced into pointer - objects. */ - argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); - } - - /* Signal end of arglist. */ - argvec[tem] = 0; - - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - - if (op == OP_ADL_FUNC) - { - struct symbol *symp; - char *func_name; - int name_len; - int string_pc = save_pos1 + 3; - - /* Extract the function name. */ - name_len = longest_to_int (exp->elts[string_pc].longconst); - func_name = (char *) alloca (name_len + 1); - strcpy (func_name, &exp->elts[string_pc + 1].string); - - find_overload_match (gdb::make_array_view (&argvec[1], nargs), - func_name, - NON_METHOD, /* not method */ - NULL, NULL, /* pass NULL symbol since - symbol is unknown */ - NULL, &symp, NULL, 0, noside); - - /* Now fix the expression being evaluated. */ - exp->elts[save_pos1 + 2].symbol = symp; - argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside); - } - - if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR - || (op == OP_SCOPE && function_name != NULL)) - { - int static_memfuncp; - char *tstr; - - /* Method invocation: stuff "this" as first parameter. If the - method turns out to be static we undo this below. */ - argvec[1] = arg2; - - if (op != OP_SCOPE) - { - /* Name of method from expression. */ - tstr = &exp->elts[pc2 + 2].string; - } - else - tstr = function_name; - - if (overload_resolution && (exp->language_defn->la_language - == language_cplus)) - { - /* Language is C++, do some overload resolution before - evaluation. */ - struct value *valp = NULL; - - (void) find_overload_match (gdb::make_array_view (&argvec[1], nargs), - tstr, - METHOD, /* method */ - &arg2, /* the object */ - NULL, &valp, NULL, - &static_memfuncp, 0, noside); - - if (op == OP_SCOPE && !static_memfuncp) - { - /* For the time being, we don't handle this. */ - error (_("Call to overloaded function %s requires " - "`this' pointer"), - function_name); - } - argvec[1] = arg2; /* the ``this'' pointer */ - argvec[0] = valp; /* Use the method found after overload - resolution. */ - } - else - /* Non-C++ case -- or no overload resolution. */ - { - struct value *temp = arg2; - - argvec[0] = value_struct_elt (&temp, argvec + 1, tstr, - &static_memfuncp, - op == STRUCTOP_STRUCT - ? "structure" : "structure pointer"); - /* value_struct_elt updates temp with the correct value of - the ``this'' pointer if necessary, so modify argvec[1] to - reflect any ``this'' changes. */ - arg2 - = value_from_longest (lookup_pointer_type(value_type (temp)), - value_address (temp) - + value_embedded_offset (temp)); - argvec[1] = arg2; /* the ``this'' pointer */ - } - - /* Take out `this' if needed. */ - if (static_memfuncp) - { - argvec[1] = argvec[0]; - nargs--; - argvec++; - } - } - else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) - { - /* Pointer to member. argvec[1] is already set up. */ - argvec[0] = arg1; - } - else if (op == OP_VAR_VALUE || (op == OP_SCOPE && function != NULL)) - { - /* Non-member function being called. */ - /* fn: This can only be done for C++ functions. A C-style - function in a C++ program, for instance, does not have the - fields that are expected here. */ - - if (overload_resolution && (exp->language_defn->la_language - == language_cplus)) - { - /* Language is C++, do some overload resolution before - evaluation. */ - struct symbol *symp; - int no_adl = 0; - - /* If a scope has been specified disable ADL. */ - if (op == OP_SCOPE) - no_adl = 1; - - if (op == OP_VAR_VALUE) - function = exp->elts[save_pos1+2].symbol; - - (void) find_overload_match (gdb::make_array_view (&argvec[1], nargs), - NULL, /* no need for name */ - NON_METHOD, /* not method */ - NULL, function, /* the function */ - NULL, &symp, NULL, no_adl, noside); - - if (op == OP_VAR_VALUE) - { - /* Now fix the expression being evaluated. */ - exp->elts[save_pos1+2].symbol = symp; - argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, - noside); - } - else - argvec[0] = value_of_variable (symp, get_selected_block (0)); - } - else - { - /* Not C++, or no overload resolution allowed. */ - /* Nothing to be done; argvec already correctly set up. */ - } - } - else - { - /* It is probably a C-style function. */ - /* Nothing to be done; argvec already correctly set up. */ - } - - return evaluate_subexp_do_call (exp, noside, argvec[0], - gdb::make_array_view (argvec + 1, nargs), - var_func_name, expect_type); -} - namespace expr { @@ -3066,738 +2531,6 @@ array_operation::evaluate (struct type *expect_type, } -struct value * -evaluate_subexp_standard (struct type *expect_type, - struct expression *exp, int *pos, - enum noside noside) -{ - enum exp_opcode op; - int tem, tem2, tem3; - int pc, oldpos; - struct value *arg1 = NULL; - struct value *arg2 = NULL; - struct type *type; - int nargs; - struct value **argvec; - int ix; - struct type **arg_types; - - pc = (*pos)++; - op = exp->elts[pc].opcode; - - switch (op) - { - case OP_SCOPE: - tem = longest_to_int (exp->elts[pc + 2].longconst); - (*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1); - return eval_op_scope (expect_type, exp, noside, - exp->elts[pc + 1].type, - &exp->elts[pc + 3].string); - - case OP_LONG: - (*pos) += 3; - return value_from_longest (exp->elts[pc + 1].type, - exp->elts[pc + 2].longconst); - - case OP_FLOAT: - (*pos) += 3; - return value_from_contents (exp->elts[pc + 1].type, - exp->elts[pc + 2].floatconst); - - case OP_ADL_FUNC: - case OP_VAR_VALUE: - { - (*pos) += 3; - symbol *var = exp->elts[pc + 2].symbol; - if (SYMBOL_TYPE (var)->code () == TYPE_CODE_ERROR) - error_unknown_type (var->print_name ()); - if (noside != EVAL_SKIP) - return evaluate_var_value (noside, exp->elts[pc + 1].block, var); - else - { - /* Return a dummy value of the correct type when skipping, so - that parent functions know what is to be skipped. */ - return allocate_value (SYMBOL_TYPE (var)); - } - } - - case OP_VAR_MSYM_VALUE: - { - (*pos) += 3; - - minimal_symbol *msymbol = exp->elts[pc + 2].msymbol; - return eval_op_var_msym_value (expect_type, exp, noside, - pc == 0, msymbol, - exp->elts[pc + 1].objfile); - } - - case OP_VAR_ENTRY_VALUE: - (*pos) += 2; - - { - struct symbol *sym = exp->elts[pc + 1].symbol; - - return eval_op_var_entry_value (expect_type, exp, noside, sym); - } - - case OP_FUNC_STATIC_VAR: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - - { - value *func = evaluate_subexp_standard (NULL, exp, pos, noside); - - return eval_op_func_static_var (expect_type, exp, noside, func, - &exp->elts[pc + 2].string); - } - - case OP_LAST: - (*pos) += 2; - return - access_value_history (longest_to_int (exp->elts[pc + 1].longconst)); - - case OP_REGISTER: - { - const char *name = &exp->elts[pc + 2].string; - - (*pos) += 3 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1); - return eval_op_register (expect_type, exp, noside, name); - } - case OP_BOOL: - (*pos) += 2; - type = language_bool_type (exp->language_defn, exp->gdbarch); - return value_from_longest (type, exp->elts[pc + 1].longconst); - - case OP_INTERNALVAR: - (*pos) += 2; - return value_of_internalvar (exp->gdbarch, - exp->elts[pc + 1].internalvar); - - case OP_STRING: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - return eval_op_string (expect_type, exp, noside, tem, - &exp->elts[pc + 2].string); - - case OP_OBJC_NSSTRING: /* Objective C Foundation Class - NSString constant. */ - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - return value_nsstring (exp->gdbarch, &exp->elts[pc + 2].string, tem + 1); - - case OP_ARRAY: - (*pos) += 3; - tem2 = longest_to_int (exp->elts[pc + 1].longconst); - tem3 = longest_to_int (exp->elts[pc + 2].longconst); - nargs = tem3 - tem2 + 1; - type = expect_type ? check_typedef (expect_type) : nullptr; - - if (expect_type != nullptr && noside != EVAL_SKIP - && type->code () == TYPE_CODE_STRUCT) - { - struct value *rec = allocate_value (expect_type); - - memset (value_contents_raw (rec), '\0', TYPE_LENGTH (type)); - return evaluate_struct_tuple (rec, exp, pos, noside, nargs); - } - - if (expect_type != nullptr && noside != EVAL_SKIP - && type->code () == TYPE_CODE_ARRAY) - { - struct type *range_type = type->index_type (); - struct type *element_type = TYPE_TARGET_TYPE (type); - struct value *array = allocate_value (expect_type); - int element_size = TYPE_LENGTH (check_typedef (element_type)); - LONGEST low_bound, high_bound, index; - - if (!get_discrete_bounds (range_type, &low_bound, &high_bound)) - { - low_bound = 0; - high_bound = (TYPE_LENGTH (type) / element_size) - 1; - } - index = low_bound; - memset (value_contents_raw (array), 0, TYPE_LENGTH (expect_type)); - for (tem = nargs; --nargs >= 0;) - { - struct value *element; - - element = evaluate_subexp (element_type, exp, pos, noside); - if (value_type (element) != element_type) - element = value_cast (element_type, element); - if (index > high_bound) - /* To avoid memory corruption. */ - error (_("Too many array elements")); - memcpy (value_contents_raw (array) - + (index - low_bound) * element_size, - value_contents (element), - element_size); - index++; - } - return array; - } - - if (expect_type != nullptr && noside != EVAL_SKIP - && type->code () == TYPE_CODE_SET) - { - struct value *set = allocate_value (expect_type); - gdb_byte *valaddr = value_contents_raw (set); - struct type *element_type = type->index_type (); - struct type *check_type = element_type; - LONGEST low_bound, high_bound; - - /* Get targettype of elementtype. */ - while (check_type->code () == TYPE_CODE_RANGE - || check_type->code () == TYPE_CODE_TYPEDEF) - check_type = TYPE_TARGET_TYPE (check_type); - - if (!get_discrete_bounds (element_type, &low_bound, &high_bound)) - error (_("(power)set type with unknown size")); - memset (valaddr, '\0', TYPE_LENGTH (type)); - for (tem = 0; tem < nargs; tem++) - { - LONGEST range_low, range_high; - struct type *range_low_type, *range_high_type; - struct value *elem_val; - - elem_val = evaluate_subexp (element_type, exp, pos, noside); - range_low_type = range_high_type = value_type (elem_val); - range_low = range_high = value_as_long (elem_val); - - /* Check types of elements to avoid mixture of elements from - different types. Also check if type of element is "compatible" - with element type of powerset. */ - if (range_low_type->code () == TYPE_CODE_RANGE) - range_low_type = TYPE_TARGET_TYPE (range_low_type); - if (range_high_type->code () == TYPE_CODE_RANGE) - range_high_type = TYPE_TARGET_TYPE (range_high_type); - if ((range_low_type->code () != range_high_type->code ()) - || (range_low_type->code () == TYPE_CODE_ENUM - && (range_low_type != range_high_type))) - /* different element modes. */ - error (_("POWERSET tuple elements of different mode")); - if ((check_type->code () != range_low_type->code ()) - || (check_type->code () == TYPE_CODE_ENUM - && range_low_type != check_type)) - error (_("incompatible POWERSET tuple elements")); - if (range_low > range_high) - { - warning (_("empty POWERSET tuple range")); - continue; - } - if (range_low < low_bound || range_high > high_bound) - error (_("POWERSET tuple element out of range")); - range_low -= low_bound; - range_high -= low_bound; - for (; range_low <= range_high; range_low++) - { - int bit_index = (unsigned) range_low % TARGET_CHAR_BIT; - - if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG) - bit_index = TARGET_CHAR_BIT - 1 - bit_index; - valaddr[(unsigned) range_low / TARGET_CHAR_BIT] - |= 1 << bit_index; - } - } - return set; - } - - argvec = XALLOCAVEC (struct value *, nargs); - for (tem = 0; tem < nargs; tem++) - { - /* Ensure that array expressions are coerced into pointer - objects. */ - argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); - } - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - return value_array (tem2, tem3, argvec); - - case TERNOP_SLICE: - { - struct value *array = evaluate_subexp (nullptr, exp, pos, noside); - struct value *low = evaluate_subexp (nullptr, exp, pos, noside); - struct value *upper = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_ternop (expect_type, exp, noside, array, low, upper); - } - - case TERNOP_COND: - /* Skip third and second args to evaluate the first one. */ - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - if (value_logical_not (arg1)) - { - evaluate_subexp (nullptr, exp, pos, EVAL_SKIP); - return evaluate_subexp (nullptr, exp, pos, noside); - } - else - { - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - evaluate_subexp (nullptr, exp, pos, EVAL_SKIP); - return arg2; - } - - case OP_OBJC_SELECTOR: - { /* Objective C @selector operator. */ - char *sel = &exp->elts[pc + 2].string; - int len = longest_to_int (exp->elts[pc + 1].longconst); - - (*pos) += 3 + BYTES_TO_EXP_ELEM (len + 1); - if (sel[len] != 0) - sel[len] = 0; /* Make sure it's terminated. */ - - return eval_op_objc_selector (expect_type, exp, noside, sel); - } - - case OP_OBJC_MSGCALL: - { /* Objective C message (method) call. */ - CORE_ADDR selector = 0; - - enum noside sub_no_side = EVAL_NORMAL; - - struct value *target = NULL; - - struct type *selector_type = NULL; - - selector = exp->elts[pc + 1].longconst; - nargs = exp->elts[pc + 2].longconst; - argvec = XALLOCAVEC (struct value *, nargs + 3); - - (*pos) += 3; - - selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr; - - if (noside == EVAL_AVOID_SIDE_EFFECTS) - sub_no_side = EVAL_NORMAL; - else - sub_no_side = noside; - - target = evaluate_subexp (selector_type, exp, pos, sub_no_side); - - if (value_as_long (target) == 0) - sub_no_side = EVAL_SKIP; - else - sub_no_side = noside; - - /* Now depending on whether we found a symbol for the method, - we will either call the runtime dispatcher or the method - directly. */ - - argvec[0] = nullptr; - argvec[1] = nullptr; - /* User-supplied arguments. */ - for (tem = 0; tem < nargs; tem++) - argvec[tem + 2] = evaluate_subexp_with_coercion (exp, pos, - sub_no_side); - argvec[tem + 3] = 0; - - auto call_args = gdb::make_array_view (argvec, nargs + 3); - - return eval_op_objc_msgcall (expect_type, exp, noside, selector, - target, call_args); - } - break; - - case OP_FUNCALL: - return evaluate_funcall (expect_type, exp, pos, noside); - - case OP_COMPLEX: - /* We have a complex number, There should be 2 floating - point numbers that compose it. */ - (*pos) += 2; - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - - return value_literal_complex (arg1, arg2, exp->elts[pc + 1].type); - - case STRUCTOP_STRUCT: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_structop_struct (expect_type, exp, noside, arg1, - &exp->elts[pc + 2].string); - - case STRUCTOP_PTR: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_structop_ptr (expect_type, exp, noside, arg1, - &exp->elts[pc + 2].string); - - case STRUCTOP_MEMBER: - case STRUCTOP_MPTR: - if (op == STRUCTOP_MEMBER) - arg1 = evaluate_subexp_for_address (exp, pos, noside); - else - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - - return eval_op_member (expect_type, exp, noside, arg1, arg2); - - case TYPE_INSTANCE: - { - type_instance_flags flags - = (type_instance_flag_value) longest_to_int (exp->elts[pc + 1].longconst); - nargs = longest_to_int (exp->elts[pc + 2].longconst); - arg_types = (struct type **) alloca (nargs * sizeof (struct type *)); - for (ix = 0; ix < nargs; ++ix) - arg_types[ix] = exp->elts[pc + 2 + ix + 1].type; - - fake_method fake_expect_type (flags, nargs, arg_types); - *(pos) += 4 + nargs; - return evaluate_subexp_standard (fake_expect_type.type (), exp, pos, - noside); - } - - case BINOP_CONCAT: - arg1 = evaluate_subexp_with_coercion (exp, pos, noside); - arg2 = evaluate_subexp_with_coercion (exp, pos, noside); - return eval_op_concat (expect_type, exp, noside, arg1, arg2); - - case BINOP_ASSIGN: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - /* Special-case assignments where the left-hand-side is a - convenience variable -- in these, don't bother setting an - expected type. This avoids a weird case where re-assigning a - string or array to an internal variable could error with "Too - many array elements". */ - arg2 = evaluate_subexp (VALUE_LVAL (arg1) == lval_internalvar - ? nullptr - : value_type (arg1), - exp, pos, noside); - - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) - return arg1; - if (binop_user_defined_p (op, arg1, arg2)) - return value_x_binop (arg1, arg2, op, OP_NULL, noside); - else - return value_assign (arg1, arg2); - - case BINOP_ASSIGN_MODIFY: - (*pos) += 2; - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); - op = exp->elts[pc + 1].opcode; - return eval_binop_assign_modify (expect_type, exp, noside, op, - arg1, arg2); - - case BINOP_ADD: - arg1 = evaluate_subexp_with_coercion (exp, pos, noside); - arg2 = evaluate_subexp_with_coercion (exp, pos, noside); - return eval_op_add (expect_type, exp, noside, arg1, arg2); - - case BINOP_SUB: - arg1 = evaluate_subexp_with_coercion (exp, pos, noside); - arg2 = evaluate_subexp_with_coercion (exp, pos, noside); - return eval_op_sub (expect_type, exp, noside, arg1, arg2); - - case BINOP_EXP: - case BINOP_MUL: - case BINOP_DIV: - case BINOP_INTDIV: - case BINOP_REM: - case BINOP_MOD: - case BINOP_LSH: - case BINOP_RSH: - case BINOP_BITWISE_AND: - case BINOP_BITWISE_IOR: - case BINOP_BITWISE_XOR: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_binary (expect_type, exp, noside, op, arg1, arg2); - - case BINOP_SUBSCRIPT: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_subscript (expect_type, exp, noside, op, arg1, arg2); - - case MULTI_SUBSCRIPT: - (*pos) += 2; - nargs = longest_to_int (exp->elts[pc + 1].longconst); - arg1 = evaluate_subexp_with_coercion (exp, pos, noside); - argvec = XALLOCAVEC (struct value *, nargs); - for (ix = 0; ix < nargs; ++ix) - argvec[ix] = evaluate_subexp_with_coercion (exp, pos, noside); - return eval_multi_subscript (expect_type, exp, noside, arg1, - gdb::make_array_view (argvec, nargs)); - - case BINOP_LOGICAL_AND: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - if (noside == EVAL_SKIP) - { - evaluate_subexp (nullptr, exp, pos, noside); - return eval_skip_value (exp); - } - - oldpos = *pos; - arg2 = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - *pos = oldpos; - - if (binop_user_defined_p (op, arg1, arg2)) - { - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - return value_x_binop (arg1, arg2, op, OP_NULL, noside); - } - else - { - tem = value_logical_not (arg1); - arg2 - = evaluate_subexp (nullptr, exp, pos, (tem ? EVAL_SKIP : noside)); - type = language_bool_type (exp->language_defn, exp->gdbarch); - return value_from_longest (type, - (LONGEST) (!tem && !value_logical_not (arg2))); - } - - case BINOP_LOGICAL_OR: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - if (noside == EVAL_SKIP) - { - evaluate_subexp (nullptr, exp, pos, noside); - return eval_skip_value (exp); - } - - oldpos = *pos; - arg2 = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - *pos = oldpos; - - if (binop_user_defined_p (op, arg1, arg2)) - { - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - return value_x_binop (arg1, arg2, op, OP_NULL, noside); - } - else - { - tem = value_logical_not (arg1); - arg2 - = evaluate_subexp (nullptr, exp, pos, (!tem ? EVAL_SKIP : noside)); - type = language_bool_type (exp->language_defn, exp->gdbarch); - return value_from_longest (type, - (LONGEST) (!tem || !value_logical_not (arg2))); - } - - case BINOP_EQUAL: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); - return eval_op_equal (expect_type, exp, noside, op, arg1, arg2); - - case BINOP_NOTEQUAL: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); - return eval_op_notequal (expect_type, exp, noside, op, arg1, arg2); - - case BINOP_LESS: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); - return eval_op_less (expect_type, exp, noside, op, arg1, arg2); - - case BINOP_GTR: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); - return eval_op_gtr (expect_type, exp, noside, op, arg1, arg2); - - case BINOP_GEQ: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); - return eval_op_geq (expect_type, exp, noside, op, arg1, arg2); - - case BINOP_LEQ: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); - return eval_op_leq (expect_type, exp, noside, op, arg1, arg2); - - case BINOP_REPEAT: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_repeat (expect_type, exp, noside, op, arg1, arg2); - - case BINOP_COMMA: - evaluate_subexp (nullptr, exp, pos, noside); - return evaluate_subexp (nullptr, exp, pos, noside); - - case UNOP_PLUS: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_plus (expect_type, exp, noside, op, arg1); - - case UNOP_NEG: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_neg (expect_type, exp, noside, op, arg1); - - case UNOP_COMPLEMENT: - /* C++: check for and handle destructor names. */ - - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_complement (expect_type, exp, noside, op, arg1); - - case UNOP_LOGICAL_NOT: - arg1 = evaluate_subexp (nullptr, exp, pos, noside); - return eval_op_lognot (expect_type, exp, noside, op, arg1); - - case UNOP_IND: - if (expect_type && expect_type->code () == TYPE_CODE_PTR) - expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type)); - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - return eval_op_ind (expect_type, exp, noside, arg1); - - case UNOP_ADDR: - /* C++: check for and handle pointer to members. */ - - if (noside == EVAL_SKIP) - { - evaluate_subexp (nullptr, exp, pos, EVAL_SKIP); - return eval_skip_value (exp); - } - else - return evaluate_subexp_for_address (exp, pos, noside); - - case UNOP_SIZEOF: - if (noside == EVAL_SKIP) - { - evaluate_subexp (nullptr, exp, pos, EVAL_SKIP); - return eval_skip_value (exp); - } - return evaluate_subexp_for_sizeof (exp, pos, noside); - - case UNOP_ALIGNOF: - arg1 = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - return eval_op_alignof (expect_type, exp, noside, arg1); - - case UNOP_CAST: - (*pos) += 2; - type = exp->elts[pc + 1].type; - return evaluate_subexp_for_cast (exp, pos, noside, type); - - case UNOP_CAST_TYPE: - arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - type = value_type (arg1); - return evaluate_subexp_for_cast (exp, pos, noside, type); - - case UNOP_DYNAMIC_CAST: - arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - type = value_type (arg1); - arg1 = evaluate_subexp (type, exp, pos, noside); - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - return value_dynamic_cast (type, arg1); - - case UNOP_REINTERPRET_CAST: - arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - type = value_type (arg1); - arg1 = evaluate_subexp (type, exp, pos, noside); - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - return value_reinterpret_cast (type, arg1); - - case UNOP_MEMVAL: - (*pos) += 2; - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - return eval_op_memval (expect_type, exp, noside, arg1, - exp->elts[pc + 1].type); - - case UNOP_MEMVAL_TYPE: - arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - type = value_type (arg1); - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - return eval_op_memval (expect_type, exp, noside, arg1, type); - - case UNOP_PREINCREMENT: - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - return eval_op_preinc (expect_type, exp, noside, op, arg1); - - case UNOP_PREDECREMENT: - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - return eval_op_predec (expect_type, exp, noside, op, arg1); - - case UNOP_POSTINCREMENT: - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - return eval_op_postinc (expect_type, exp, noside, op, arg1); - - case UNOP_POSTDECREMENT: - arg1 = evaluate_subexp (expect_type, exp, pos, noside); - return eval_op_postdec (expect_type, exp, noside, op, arg1); - - case OP_THIS: - (*pos) += 1; - return value_of_this (exp->language_defn); - - case OP_TYPE: - /* The value is not supposed to be used. This is here to make it - easier to accommodate expressions that contain types. */ - (*pos) += 2; - return eval_op_type (expect_type, exp, noside, exp->elts[pc + 1].type); - - case OP_TYPEOF: - case OP_DECLTYPE: - if (noside == EVAL_SKIP) - { - evaluate_subexp (nullptr, exp, pos, EVAL_SKIP); - return eval_skip_value (exp); - } - else if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - enum exp_opcode sub_op = exp->elts[*pos].opcode; - struct value *result; - - result = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - - /* 'decltype' has special semantics for lvalues. */ - if (op == OP_DECLTYPE - && (sub_op == BINOP_SUBSCRIPT - || sub_op == STRUCTOP_MEMBER - || sub_op == STRUCTOP_MPTR - || sub_op == UNOP_IND - || sub_op == STRUCTOP_STRUCT - || sub_op == STRUCTOP_PTR - || sub_op == OP_SCOPE)) - { - type = value_type (result); - - if (!TYPE_IS_REFERENCE (type)) - { - type = lookup_lvalue_reference_type (type); - result = allocate_value (type); - } - } - - return result; - } - else - error (_("Attempt to use a type as an expression")); - - case OP_TYPEID: - { - struct value *result; - enum exp_opcode sub_op = exp->elts[*pos].opcode; - - if (sub_op == OP_TYPE || sub_op == OP_DECLTYPE || sub_op == OP_TYPEOF) - result = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - else - result = evaluate_subexp (nullptr, exp, pos, noside); - - if (noside != EVAL_NORMAL) - return allocate_value (cplus_typeid_type (exp->gdbarch)); - - return cplus_typeid (result); - } - - default: - /* Removing this case and compiling with gcc -Wall reveals that - a lot of cases are hitting this case. Some of these should - probably be removed from expression.h; others are legitimate - expressions which are (apparently) not fully implemented. - - If there are any cases landing here which mean a user error, - then they should be separate cases, with more descriptive - error messages. */ - - error (_("GDB does not (yet) know how to " - "evaluate that kind of expression")); - } - - gdb_assert_not_reached ("missed return?"); -} /* Helper for evaluate_subexp_for_address. */ @@ -3822,117 +2555,6 @@ evaluate_subexp_for_address_base (struct expression *exp, enum noside noside, return value_addr (x); } -/* Evaluate a subexpression of EXP, at index *POS, - and return the address of that subexpression. - Advance *POS over the subexpression. - If the subexpression isn't an lvalue, get an error. - NOSIDE may be EVAL_AVOID_SIDE_EFFECTS; - then only the type of the result need be correct. */ - -static struct value * -evaluate_subexp_for_address (struct expression *exp, int *pos, - enum noside noside) -{ - enum exp_opcode op; - int pc; - struct symbol *var; - struct value *x; - int tem; - - pc = (*pos); - op = exp->elts[pc].opcode; - - switch (op) - { - case UNOP_IND: - (*pos)++; - x = evaluate_subexp (nullptr, exp, pos, noside); - - /* We can't optimize out "&*" if there's a user-defined operator*. */ - if (unop_user_defined_p (op, x)) - { - x = value_x_unop (x, op, noside); - goto default_case_after_eval; - } - - return coerce_array (x); - - case UNOP_MEMVAL: - (*pos) += 3; - return value_cast (lookup_pointer_type (exp->elts[pc + 1].type), - evaluate_subexp (nullptr, exp, pos, noside)); - - case UNOP_MEMVAL_TYPE: - { - struct type *type; - - (*pos) += 1; - x = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - type = value_type (x); - return value_cast (lookup_pointer_type (type), - evaluate_subexp (nullptr, exp, pos, noside)); - } - - case OP_VAR_VALUE: - var = exp->elts[pc + 2].symbol; - - /* C++: The "address" of a reference should yield the address - * of the object pointed to. Let value_addr() deal with it. */ - if (TYPE_IS_REFERENCE (SYMBOL_TYPE (var))) - goto default_case; - - (*pos) += 4; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - struct type *type = - lookup_pointer_type (SYMBOL_TYPE (var)); - enum address_class sym_class = SYMBOL_CLASS (var); - - if (sym_class == LOC_CONST - || sym_class == LOC_CONST_BYTES - || sym_class == LOC_REGISTER) - error (_("Attempt to take address of register or constant.")); - - return - value_zero (type, not_lval); - } - else - return address_of_variable (var, exp->elts[pc + 1].block); - - case OP_VAR_MSYM_VALUE: - { - (*pos) += 4; - - value *val = evaluate_var_msym_value (noside, - exp->elts[pc + 1].objfile, - exp->elts[pc + 2].msymbol); - if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - struct type *type = lookup_pointer_type (value_type (val)); - return value_zero (type, not_lval); - } - else - return value_addr (val); - } - - case OP_SCOPE: - tem = longest_to_int (exp->elts[pc + 2].longconst); - (*pos) += 5 + BYTES_TO_EXP_ELEM (tem + 1); - x = value_aggregate_elt (exp->elts[pc + 1].type, - &exp->elts[pc + 3].string, - NULL, 1, noside); - if (x == NULL) - error (_("There is no field named %s"), &exp->elts[pc + 3].string); - return x; - - default: - default_case: - x = evaluate_subexp (nullptr, exp, pos, noside); - default_case_after_eval: - return evaluate_subexp_for_address_base (exp, noside, x); - } -} - namespace expr { @@ -4019,51 +2641,6 @@ unop_memval_type_operation::evaluate_for_address (struct expression *exp, } -/* Evaluate like `evaluate_subexp' except coercing arrays to pointers. - When used in contexts where arrays will be coerced anyway, this is - equivalent to `evaluate_subexp' but much faster because it avoids - actually fetching array contents (perhaps obsolete now that we have - value_lazy()). - - Note that we currently only do the coercion for C expressions, where - arrays are zero based and the coercion is correct. For other languages, - with nonzero based arrays, coercion loses. Use CAST_IS_CONVERSION - to decide if coercion is appropriate. */ - -struct value * -evaluate_subexp_with_coercion (struct expression *exp, - int *pos, enum noside noside) -{ - enum exp_opcode op; - int pc; - struct value *val; - struct symbol *var; - struct type *type; - - pc = (*pos); - op = exp->elts[pc].opcode; - - switch (op) - { - case OP_VAR_VALUE: - var = exp->elts[pc + 2].symbol; - type = check_typedef (SYMBOL_TYPE (var)); - if (type->code () == TYPE_CODE_ARRAY - && !type->is_vector () - && CAST_IS_CONVERSION (exp->language_defn)) - { - (*pos) += 4; - val = address_of_variable (var, exp->elts[pc + 1].block); - return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), - val); - } - /* FALLTHROUGH */ - - default: - return evaluate_subexp (nullptr, exp, pos, noside); - } -} - namespace expr { @@ -4129,132 +2706,6 @@ evaluate_subexp_for_sizeof_base (struct expression *exp, struct type *type) return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); } -/* Evaluate a subexpression of EXP, at index *POS, - and return a value for the size of that subexpression. - Advance *POS over the subexpression. If NOSIDE is EVAL_NORMAL - we allow side-effects on the operand if its type is a variable - length array. */ - -static struct value * -evaluate_subexp_for_sizeof (struct expression *exp, int *pos, - enum noside noside) -{ - /* FIXME: This should be size_t. */ - struct type *size_type = builtin_type (exp->gdbarch)->builtin_int; - enum exp_opcode op; - int pc; - struct type *type; - struct value *val; - - pc = (*pos); - op = exp->elts[pc].opcode; - - switch (op) - { - /* This case is handled specially - so that we avoid creating a value for the result type. - If the result type is very big, it's desirable not to - create a value unnecessarily. */ - case UNOP_IND: - (*pos)++; - val = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - type = check_typedef (value_type (val)); - if (type->code () != TYPE_CODE_PTR - && !TYPE_IS_REFERENCE (type) - && type->code () != TYPE_CODE_ARRAY) - error (_("Attempt to take contents of a non-pointer value.")); - type = TYPE_TARGET_TYPE (type); - if (is_dynamic_type (type)) - type = value_type (value_ind (val)); - return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); - - case UNOP_MEMVAL: - (*pos) += 3; - type = exp->elts[pc + 1].type; - break; - - case UNOP_MEMVAL_TYPE: - (*pos) += 1; - val = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - type = value_type (val); - break; - - case OP_VAR_VALUE: - type = SYMBOL_TYPE (exp->elts[pc + 2].symbol); - if (is_dynamic_type (type)) - { - val = evaluate_subexp (nullptr, exp, pos, EVAL_NORMAL); - type = value_type (val); - if (type->code () == TYPE_CODE_ARRAY) - { - if (type_not_allocated (type) || type_not_associated (type)) - return value_zero (size_type, not_lval); - else if (is_dynamic_type (type->index_type ()) - && type->bounds ()->high.kind () == PROP_UNDEFINED) - return allocate_optimized_out_value (size_type); - } - } - else - (*pos) += 4; - break; - - case OP_VAR_MSYM_VALUE: - { - (*pos) += 4; - - minimal_symbol *msymbol = exp->elts[pc + 2].msymbol; - value *mval = evaluate_var_msym_value (noside, - exp->elts[pc + 1].objfile, - msymbol); - - type = value_type (mval); - if (type->code () == TYPE_CODE_ERROR) - error_unknown_type (msymbol->print_name ()); - - return value_from_longest (size_type, TYPE_LENGTH (type)); - } - break; - - /* Deal with the special case if NOSIDE is EVAL_NORMAL and the resulting - type of the subscript is a variable length array type. In this case we - must re-evaluate the right hand side of the subscription to allow - side-effects. */ - case BINOP_SUBSCRIPT: - if (noside == EVAL_NORMAL) - { - int npc = (*pos) + 1; - - val = evaluate_subexp (nullptr, exp, &npc, EVAL_AVOID_SIDE_EFFECTS); - type = check_typedef (value_type (val)); - if (type->code () == TYPE_CODE_ARRAY) - { - type = check_typedef (TYPE_TARGET_TYPE (type)); - if (type->code () == TYPE_CODE_ARRAY) - { - type = type->index_type (); - /* Only re-evaluate the right hand side if the resulting type - is a variable length type. */ - if (type->bounds ()->flag_bound_evaluated) - { - val = evaluate_subexp (nullptr, exp, pos, EVAL_NORMAL); - return value_from_longest - (size_type, (LONGEST) TYPE_LENGTH (value_type (val))); - } - } - } - } - - /* Fall through. */ - - default: - val = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - type = value_type (val); - break; - } - - return evaluate_subexp_for_sizeof_base (exp, type); -} - namespace expr { @@ -4377,61 +2828,6 @@ var_value_operation::evaluate_for_sizeof (struct expression *exp, } -/* Evaluate a subexpression of EXP, at index *POS, and return a value - for that subexpression cast to TO_TYPE. Advance *POS over the - subexpression. */ - -static value * -evaluate_subexp_for_cast (expression *exp, int *pos, - enum noside noside, - struct type *to_type) -{ - int pc = *pos; - - /* Don't let symbols be evaluated with evaluate_subexp because that - throws an "unknown type" error for no-debug data symbols. - Instead, we want the cast to reinterpret the symbol. */ - if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE - || exp->elts[pc].opcode == OP_VAR_VALUE) - { - (*pos) += 4; - - value *val; - if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE) - { - if (noside == EVAL_AVOID_SIDE_EFFECTS) - return value_zero (to_type, not_lval); - - val = evaluate_var_msym_value (noside, - exp->elts[pc + 1].objfile, - exp->elts[pc + 2].msymbol); - } - else - val = evaluate_var_value (noside, - exp->elts[pc + 1].block, - exp->elts[pc + 2].symbol); - - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - - val = value_cast (to_type, val); - - /* Don't allow e.g. '&(int)var_with_no_debug_info'. */ - if (VALUE_LVAL (val) == lval_memory) - { - if (value_lazy (val)) - value_fetch_lazy (val); - VALUE_LVAL (val) = not_lval; - } - return val; - } - - value *val = evaluate_subexp (to_type, exp, pos, noside); - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - return value_cast (to_type, val); -} - namespace expr { @@ -4501,15 +2897,9 @@ parse_and_eval_type (const char *p, int length) tmp[length + 2] = '0'; tmp[length + 3] = '\0'; expression_up expr = parse_expression (tmp); - if (expr->first_opcode () != UNOP_CAST) + expr::unop_cast_operation *op + = dynamic_cast<expr::unop_cast_operation *> (expr->op.get ()); + if (op == nullptr) error (_("Internal error in eval_type.")); - - if (expr->op != nullptr) - { - expr::unop_cast_operation *op - = dynamic_cast<expr::unop_cast_operation *> (expr->op.get ()); - return op->get_type (); - } - - return expr->elts[1].type; + return op->get_type (); } diff --git a/gdb/expprint.c b/gdb/expprint.c index 6c65ec0..49919e8 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -36,661 +36,6 @@ #include <ctype.h> -void -print_expression (struct expression *exp, struct ui_file *stream) -{ - int pc = 0; - - print_subexp (exp, &pc, stream, PREC_NULL); -} - -/* Print the subexpression of EXP that starts in position POS, on STREAM. - PREC is the precedence of the surrounding operator; - if the precedence of the main operator of this subexpression is less, - parentheses are needed here. */ - -void -print_subexp (struct expression *exp, int *pos, - struct ui_file *stream, enum precedence prec) -{ - exp->language_defn->expression_ops ()->print_subexp (exp, pos, stream, - prec); -} - -/* See parser-defs.h. */ - -void -print_subexp_funcall (struct expression *exp, int *pos, - struct ui_file *stream) -{ - unsigned nargs = longest_to_int (exp->elts[*pos].longconst); - (*pos) += 2; - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered (" (", stream); - for (unsigned tem = 0; tem < nargs; tem++) - { - if (tem != 0) - fputs_filtered (", ", stream); - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - } - fputs_filtered (")", stream); -} - -/* Standard implementation of print_subexp for use in language_defn - vectors. */ -void -print_subexp_standard (struct expression *exp, int *pos, - struct ui_file *stream, enum precedence prec) -{ - unsigned tem; - const struct op_print *op_print_tab; - int pc; - unsigned nargs; - const char *op_str; - int assign_modify = 0; - enum exp_opcode opcode; - enum precedence myprec = PREC_NULL; - /* Set to 1 for a right-associative operator. */ - int assoc = 0; - struct value *val; - char *tempstr = NULL; - - op_print_tab = exp->language_defn->opcode_print_table (); - pc = (*pos)++; - opcode = exp->elts[pc].opcode; - switch (opcode) - { - /* Common ops */ - - case OP_TYPE: - (*pos) += 2; - type_print (exp->elts[pc + 1].type, "", stream, 0); - return; - - case OP_SCOPE: - myprec = PREC_PREFIX; - assoc = 0; - fputs_filtered (exp->elts[pc + 1].type->name (), stream); - fputs_filtered ("::", stream); - nargs = longest_to_int (exp->elts[pc + 2].longconst); - (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1); - fputs_filtered (&exp->elts[pc + 3].string, stream); - return; - - case OP_LONG: - { - struct value_print_options opts; - - get_no_prettyformat_print_options (&opts); - (*pos) += 3; - value_print (value_from_longest (exp->elts[pc + 1].type, - exp->elts[pc + 2].longconst), - stream, &opts); - } - return; - - case OP_FLOAT: - { - struct value_print_options opts; - - get_no_prettyformat_print_options (&opts); - (*pos) += 3; - value_print (value_from_contents (exp->elts[pc + 1].type, - exp->elts[pc + 2].floatconst), - stream, &opts); - } - return; - - case OP_VAR_VALUE: - { - const struct block *b; - - (*pos) += 3; - b = exp->elts[pc + 1].block; - if (b != NULL - && BLOCK_FUNCTION (b) != NULL - && BLOCK_FUNCTION (b)->print_name () != NULL) - { - fputs_filtered (BLOCK_FUNCTION (b)->print_name (), stream); - fputs_filtered ("::", stream); - } - fputs_filtered (exp->elts[pc + 2].symbol->print_name (), stream); - } - return; - - case OP_VAR_MSYM_VALUE: - { - (*pos) += 3; - fputs_filtered (exp->elts[pc + 2].msymbol->print_name (), stream); - } - return; - - case OP_FUNC_STATIC_VAR: - { - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - fputs_filtered (&exp->elts[pc + 1].string, stream); - } - return; - - case OP_VAR_ENTRY_VALUE: - { - (*pos) += 2; - fprintf_filtered (stream, "%s@entry", - exp->elts[pc + 1].symbol->print_name ()); - } - return; - - case OP_LAST: - (*pos) += 2; - fprintf_filtered (stream, "$%d", - longest_to_int (exp->elts[pc + 1].longconst)); - return; - - case OP_REGISTER: - { - const char *name = &exp->elts[pc + 2].string; - - (*pos) += 3 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1); - fprintf_filtered (stream, "$%s", name); - return; - } - - case OP_BOOL: - (*pos) += 2; - fprintf_filtered (stream, "%s", - longest_to_int (exp->elts[pc + 1].longconst) - ? "TRUE" : "FALSE"); - return; - - case OP_INTERNALVAR: - (*pos) += 2; - fprintf_filtered (stream, "$%s", - internalvar_name (exp->elts[pc + 1].internalvar)); - return; - - case OP_FUNCALL: - print_subexp_funcall (exp, pos, stream); - return; - - case OP_NAME: - nargs = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); - fputs_filtered (&exp->elts[pc + 2].string, stream); - return; - - case OP_STRING: - { - struct value_print_options opts; - - nargs = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); - /* LA_PRINT_STRING will print using the current repeat count threshold. - If necessary, we can temporarily set it to zero, or pass it as an - additional parameter to LA_PRINT_STRING. -fnf */ - get_user_print_options (&opts); - exp->language_defn - ->printstr (stream, builtin_type (exp->gdbarch)->builtin_char, - (gdb_byte *) &exp->elts[pc + 2].string, nargs, - NULL, 0, &opts); - } - return; - - case OP_OBJC_NSSTRING: /* Objective-C Foundation Class - NSString constant. */ - { - struct value_print_options opts; - - nargs = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1); - fputs_filtered ("@\"", stream); - get_user_print_options (&opts); - exp->language_defn - ->printstr (stream, builtin_type (exp->gdbarch)->builtin_char, - (gdb_byte *) &exp->elts[pc + 2].string, nargs, - NULL, 0, &opts); - fputs_filtered ("\"", stream); - } - return; - - case OP_OBJC_MSGCALL: - { /* Objective C message (method) call. */ - (*pos) += 3; - nargs = longest_to_int (exp->elts[pc + 2].longconst); - fprintf_unfiltered (stream, "["); - print_subexp (exp, pos, stream, PREC_SUFFIX); - gdb::unique_xmalloc_ptr<char> selector - = target_read_string (exp->elts[pc + 1].longconst, 1024); - if (selector == nullptr) - error (_("bad selector")); - if (nargs) - { - char *s, *nextS; - - s = selector.get (); - for (tem = 0; tem < nargs; tem++) - { - nextS = strchr (s, ':'); - gdb_assert (nextS); /* Make sure we found ':'. */ - *nextS = '\0'; - fprintf_unfiltered (stream, " %s: ", s); - s = nextS + 1; - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - } - } - else - { - fprintf_unfiltered (stream, " %s", selector.get ()); - } - fprintf_unfiltered (stream, "]"); - return; - } - - case OP_ARRAY: - (*pos) += 3; - nargs = longest_to_int (exp->elts[pc + 2].longconst); - nargs -= longest_to_int (exp->elts[pc + 1].longconst); - nargs++; - tem = 0; - if (exp->elts[pc + 4].opcode == OP_LONG - && exp->elts[pc + 5].type - == builtin_type (exp->gdbarch)->builtin_char - && exp->language_defn->la_language == language_c) - { - /* Attempt to print C character arrays using string syntax. - Walk through the args, picking up one character from each - of the OP_LONG expression elements. If any array element - does not match our expection of what we should find for - a simple string, revert back to array printing. Note that - the last expression element is an explicit null terminator - byte, which doesn't get printed. */ - tempstr = (char *) alloca (nargs); - pc += 4; - while (tem < nargs) - { - if (exp->elts[pc].opcode != OP_LONG - || exp->elts[pc + 1].type - != builtin_type (exp->gdbarch)->builtin_char) - { - /* Not a simple array of char, use regular array - printing. */ - tem = 0; - break; - } - else - { - tempstr[tem++] = - longest_to_int (exp->elts[pc + 2].longconst); - pc += 4; - } - } - } - if (tem > 0) - { - struct value_print_options opts; - - get_user_print_options (&opts); - exp->language_defn - ->printstr (stream, builtin_type (exp->gdbarch)->builtin_char, - (gdb_byte *) tempstr, nargs - 1, NULL, 0, &opts); - (*pos) = pc; - } - else - { - fputs_filtered (" {", stream); - for (tem = 0; tem < nargs; tem++) - { - if (tem != 0) - { - fputs_filtered (", ", stream); - } - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - } - fputs_filtered ("}", stream); - } - return; - - case TERNOP_COND: - if ((int) prec > (int) PREC_COMMA) - fputs_filtered ("(", stream); - /* Print the subexpressions, forcing parentheses - around any binary operations within them. - This is more parentheses than are strictly necessary, - but it looks clearer. */ - print_subexp (exp, pos, stream, PREC_HYPER); - fputs_filtered (" ? ", stream); - print_subexp (exp, pos, stream, PREC_HYPER); - fputs_filtered (" : ", stream); - print_subexp (exp, pos, stream, PREC_HYPER); - if ((int) prec > (int) PREC_COMMA) - fputs_filtered (")", stream); - return; - - case TERNOP_SLICE: - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("(", stream); - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - fputs_filtered (opcode == TERNOP_SLICE ? " : " : " UP ", stream); - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - fputs_filtered (")", stream); - return; - - case STRUCTOP_STRUCT: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered (".", stream); - fputs_filtered (&exp->elts[pc + 2].string, stream); - return; - - /* Will not occur for Modula-2. */ - case STRUCTOP_PTR: - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("->", stream); - fputs_filtered (&exp->elts[pc + 2].string, stream); - return; - - case STRUCTOP_MEMBER: - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered (".*", stream); - print_subexp (exp, pos, stream, PREC_SUFFIX); - return; - - case STRUCTOP_MPTR: - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("->*", stream); - print_subexp (exp, pos, stream, PREC_SUFFIX); - return; - - case BINOP_SUBSCRIPT: - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("[", stream); - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - fputs_filtered ("]", stream); - return; - - case UNOP_POSTINCREMENT: - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("++", stream); - return; - - case UNOP_POSTDECREMENT: - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered ("--", stream); - return; - - case UNOP_CAST: - (*pos) += 2; - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered ("(", stream); - fputs_filtered ("(", stream); - type_print (exp->elts[pc + 1].type, "", stream, 0); - fputs_filtered (") ", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered (")", stream); - return; - - case UNOP_CAST_TYPE: - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered ("(", stream); - fputs_filtered ("(", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - fputs_filtered (") ", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered (")", stream); - return; - - case UNOP_DYNAMIC_CAST: - case UNOP_REINTERPRET_CAST: - fputs_filtered (opcode == UNOP_DYNAMIC_CAST ? "dynamic_cast" - : "reinterpret_cast", stream); - fputs_filtered ("<", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - fputs_filtered ("> (", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - fputs_filtered (")", stream); - return; - - case UNOP_MEMVAL: - (*pos) += 2; - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered ("(", stream); - if (exp->elts[pc + 1].type->code () == TYPE_CODE_FUNC - && exp->elts[pc + 3].opcode == OP_LONG) - { - struct value_print_options opts; - - /* We have a minimal symbol fn, probably. It's encoded - as a UNOP_MEMVAL (function-type) of an OP_LONG (int, address). - Swallow the OP_LONG (including both its opcodes); ignore - its type; print the value in the type of the MEMVAL. */ - (*pos) += 4; - val = value_at_lazy (exp->elts[pc + 1].type, - (CORE_ADDR) exp->elts[pc + 5].longconst); - get_no_prettyformat_print_options (&opts); - value_print (val, stream, &opts); - } - else - { - fputs_filtered ("{", stream); - type_print (exp->elts[pc + 1].type, "", stream, 0); - fputs_filtered ("} ", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - } - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered (")", stream); - return; - - case UNOP_MEMVAL_TYPE: - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered ("(", stream); - fputs_filtered ("{", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - fputs_filtered ("} ", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - if ((int) prec > (int) PREC_PREFIX) - fputs_filtered (")", stream); - return; - - case BINOP_ASSIGN_MODIFY: - opcode = exp->elts[pc + 1].opcode; - (*pos) += 2; - myprec = PREC_ASSIGN; - assoc = 1; - assign_modify = 1; - op_str = "???"; - for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) - if (op_print_tab[tem].opcode == opcode) - { - op_str = op_print_tab[tem].string; - break; - } - if (op_print_tab[tem].opcode != opcode) - /* Not found; don't try to keep going because we don't know how - to interpret further elements. */ - error (_("Invalid expression")); - break; - - /* C++ ops */ - - case OP_THIS: - ++(*pos); - if (exp->language_defn->name_of_this () != NULL) - fputs_filtered (exp->language_defn->name_of_this (), stream); - else - fprintf_styled (stream, metadata_style.style (), - _("<language %s has no 'this'>"), - exp->language_defn->name ()); - return; - - /* Modula-2 ops */ - - case MULTI_SUBSCRIPT: - (*pos) += 2; - nargs = longest_to_int (exp->elts[pc + 1].longconst); - print_subexp (exp, pos, stream, PREC_SUFFIX); - fprintf_unfiltered (stream, " ["); - for (tem = 0; tem < nargs; tem++) - { - if (tem != 0) - fprintf_unfiltered (stream, ", "); - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - } - fprintf_unfiltered (stream, "]"); - return; - - case BINOP_VAL: - (*pos) += 2; - fprintf_unfiltered (stream, "VAL("); - type_print (exp->elts[pc + 1].type, "", stream, 0); - fprintf_unfiltered (stream, ","); - print_subexp (exp, pos, stream, PREC_PREFIX); - fprintf_unfiltered (stream, ")"); - return; - - case TYPE_INSTANCE: - { - type_instance_flags flags - = (type_instance_flag_value) longest_to_int (exp->elts[pc + 1].longconst); - LONGEST count = exp->elts[pc + 2].longconst; - - /* The FLAGS. */ - (*pos)++; - /* The COUNT. */ - (*pos)++; - fputs_unfiltered ("TypeInstance(", stream); - while (count-- > 0) - { - type_print (exp->elts[(*pos)++].type, "", stream, 0); - if (count > 0) - fputs_unfiltered (",", stream); - } - fputs_unfiltered (",", stream); - /* Ending COUNT and ending TYPE_INSTANCE. */ - (*pos) += 2; - print_subexp (exp, pos, stream, PREC_PREFIX); - - if (flags & TYPE_INSTANCE_FLAG_CONST) - fputs_unfiltered (",const", stream); - if (flags & TYPE_INSTANCE_FLAG_VOLATILE) - fputs_unfiltered (",volatile", stream); - - fputs_unfiltered (")", stream); - return; - } - - case OP_RANGE: - { - enum range_flag range_flag; - - range_flag = (enum range_flag) - longest_to_int (exp->elts[pc + 1].longconst); - *pos += 2; - - if (range_flag & RANGE_HIGH_BOUND_EXCLUSIVE) - fputs_filtered ("EXCLUSIVE_", stream); - fputs_filtered ("RANGE(", stream); - if (!(range_flag & RANGE_LOW_BOUND_DEFAULT)) - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - fputs_filtered ("..", stream); - if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT)) - print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); - fputs_filtered (")", stream); - return; - } - - /* Default ops */ - - default: - op_str = "???"; - for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) - if (op_print_tab[tem].opcode == opcode) - { - op_str = op_print_tab[tem].string; - myprec = op_print_tab[tem].precedence; - assoc = op_print_tab[tem].right_assoc; - break; - } - if (op_print_tab[tem].opcode != opcode) - /* Not found; don't try to keep going because we don't know how - to interpret further elements. For example, this happens - if opcode is OP_TYPE. */ - error (_("Invalid expression")); - } - - /* Note that PREC_BUILTIN will always emit parentheses. */ - if ((int) myprec < (int) prec) - fputs_filtered ("(", stream); - if ((int) opcode > (int) BINOP_END) - { - if (assoc) - { - /* Unary postfix operator. */ - print_subexp (exp, pos, stream, PREC_SUFFIX); - fputs_filtered (op_str, stream); - } - else - { - /* Unary prefix operator. */ - fputs_filtered (op_str, stream); - if (myprec == PREC_BUILTIN_FUNCTION) - fputs_filtered ("(", stream); - print_subexp (exp, pos, stream, PREC_PREFIX); - if (myprec == PREC_BUILTIN_FUNCTION) - fputs_filtered (")", stream); - } - } - else - { - /* Binary operator. */ - /* Print left operand. - If operator is right-associative, - increment precedence for this operand. */ - print_subexp (exp, pos, stream, - (enum precedence) ((int) myprec + assoc)); - /* Print the operator itself. */ - if (assign_modify) - fprintf_filtered (stream, " %s= ", op_str); - else if (op_str[0] == ',') - fprintf_filtered (stream, "%s ", op_str); - else - fprintf_filtered (stream, " %s ", op_str); - /* Print right operand. - If operator is left-associative, - increment precedence for this operand. */ - print_subexp (exp, pos, stream, - (enum precedence) ((int) myprec + !assoc)); - } - - if ((int) myprec < (int) prec) - fputs_filtered (")", stream); -} - -/* Return the operator corresponding to opcode OP as - a string. NULL indicates that the opcode was not found in the - current language table. */ -const char * -op_string (enum exp_opcode op) -{ - int tem; - const struct op_print *op_print_tab; - - op_print_tab = current_language->opcode_print_table (); - for (tem = 0; op_print_tab[tem].opcode != OP_NULL; tem++) - if (op_print_tab[tem].opcode == op) - return op_print_tab[tem].string; - return NULL; -} - -/* Support for dumping the raw data from expressions in a human readable - form. */ - -static int dump_subexp_body (struct expression *exp, struct ui_file *, int); - /* Default name for the standard operator OPCODE (i.e., one defined in the definition of enum exp_opcode). */ @@ -714,470 +59,10 @@ op_name (enum exp_opcode opcode) } } -/* Print a raw dump of expression EXP to STREAM. - NOTE, if non-NULL, is printed as extra explanatory text. */ - -void -dump_raw_expression (struct expression *exp, struct ui_file *stream, - const char *note) -{ - int elt; - char *eltscan; - int eltsize; - - if (exp->op != nullptr) - return; - - fprintf_filtered (stream, "Dump of expression @ "); - gdb_print_host_address (exp, stream); - if (note) - fprintf_filtered (stream, ", %s:", note); - fprintf_filtered (stream, "\n\tLanguage %s, %d elements, %ld bytes each.\n", - exp->language_defn->name (), exp->nelts, - (long) sizeof (union exp_element)); - fprintf_filtered (stream, "\t%5s %20s %16s %s\n", "Index", "Opcode", - "Hex Value", "String Value"); - for (elt = 0; elt < exp->nelts; elt++) - { - fprintf_filtered (stream, "\t%5d ", elt); - - const char *opcode_name = op_name (exp->elts[elt].opcode); - fprintf_filtered (stream, "%20s ", opcode_name); - - print_longest (stream, 'd', 0, exp->elts[elt].longconst); - fprintf_filtered (stream, " "); - - for (eltscan = (char *) &exp->elts[elt], - eltsize = sizeof (union exp_element); - eltsize-- > 0; - eltscan++) - { - fprintf_filtered (stream, "%c", - isprint (*eltscan) ? (*eltscan & 0xFF) : '.'); - } - fprintf_filtered (stream, "\n"); - } -} - -/* Dump the subexpression of prefix expression EXP whose operator is at - position ELT onto STREAM. Returns the position of the next - subexpression in EXP. */ - -int -dump_subexp (struct expression *exp, struct ui_file *stream, int elt) -{ - static int indent = 0; - int i; - - fprintf_filtered (stream, "\n"); - fprintf_filtered (stream, "\t%5d ", elt); - - for (i = 1; i <= indent; i++) - fprintf_filtered (stream, " "); - indent += 2; - - fprintf_filtered (stream, "%-20s ", op_name (exp->elts[elt].opcode)); - - elt = dump_subexp_body (exp, stream, elt); - - indent -= 2; - - return elt; -} - -/* Dump the operands of prefix expression EXP whose opcode is at - position ELT onto STREAM. Returns the position of the next - subexpression in EXP. */ - -static int -dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt) -{ - return exp->language_defn->expression_ops ()->dump_subexp_body (exp, stream, - elt); -} - -/* See parser-defs.h. */ - -int -dump_subexp_body_funcall (struct expression *exp, - struct ui_file *stream, int elt) -{ - int nargs = longest_to_int (exp->elts[elt].longconst); - fprintf_filtered (stream, "Number of args: %d", nargs); - elt += 2; - - for (int i = 1; i <= nargs + 1; i++) - elt = dump_subexp (exp, stream, elt); - - return elt; -} - -/* Default value for subexp_body in exp_descriptor vector. */ - -int -dump_subexp_body_standard (struct expression *exp, - struct ui_file *stream, int elt) -{ - int opcode = exp->elts[elt++].opcode; - - switch (opcode) - { - case TERNOP_COND: - case TERNOP_SLICE: - elt = dump_subexp (exp, stream, elt); - /* FALL THROUGH */ - 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_ASSIGN: - case BINOP_COMMA: - case BINOP_SUBSCRIPT: - case BINOP_EXP: - case BINOP_MIN: - case BINOP_MAX: - case BINOP_INTDIV: - case BINOP_ASSIGN_MODIFY: - case BINOP_VAL: - case BINOP_CONCAT: - case BINOP_END: - case STRUCTOP_MEMBER: - case STRUCTOP_MPTR: - elt = dump_subexp (exp, stream, elt); - /* FALL THROUGH */ - case UNOP_NEG: - case UNOP_LOGICAL_NOT: - case UNOP_COMPLEMENT: - case UNOP_IND: - case UNOP_ADDR: - case UNOP_PREINCREMENT: - case UNOP_POSTINCREMENT: - case UNOP_PREDECREMENT: - case UNOP_POSTDECREMENT: - case UNOP_SIZEOF: - case UNOP_ALIGNOF: - case UNOP_PLUS: - case UNOP_CAP: - case UNOP_CHR: - case UNOP_ORD: - case UNOP_ABS: - case UNOP_FLOAT: - case UNOP_HIGH: - case UNOP_MAX: - case UNOP_MIN: - case UNOP_ODD: - case UNOP_TRUNC: - elt = dump_subexp (exp, stream, elt); - break; - case OP_LONG: - fprintf_filtered (stream, "Type @"); - gdb_print_host_address (exp->elts[elt].type, stream); - fprintf_filtered (stream, " ("); - type_print (exp->elts[elt].type, NULL, stream, 0); - fprintf_filtered (stream, "), value %ld (0x%lx)", - (long) exp->elts[elt + 1].longconst, - (long) exp->elts[elt + 1].longconst); - elt += 3; - break; - case OP_FLOAT: - fprintf_filtered (stream, "Type @"); - gdb_print_host_address (exp->elts[elt].type, stream); - fprintf_filtered (stream, " ("); - type_print (exp->elts[elt].type, NULL, stream, 0); - fprintf_filtered (stream, "), value "); - print_floating (exp->elts[elt + 1].floatconst, - exp->elts[elt].type, stream); - elt += 3; - break; - case OP_VAR_VALUE: - fprintf_filtered (stream, "Block @"); - gdb_print_host_address (exp->elts[elt].block, stream); - fprintf_filtered (stream, ", symbol @"); - gdb_print_host_address (exp->elts[elt + 1].symbol, stream); - fprintf_filtered (stream, " (%s)", - exp->elts[elt + 1].symbol->print_name ()); - elt += 3; - break; - case OP_VAR_MSYM_VALUE: - fprintf_filtered (stream, "Objfile @"); - gdb_print_host_address (exp->elts[elt].objfile, stream); - fprintf_filtered (stream, ", msymbol @"); - gdb_print_host_address (exp->elts[elt + 1].msymbol, stream); - fprintf_filtered (stream, " (%s)", - exp->elts[elt + 1].msymbol->print_name ()); - elt += 3; - break; - case OP_VAR_ENTRY_VALUE: - fprintf_filtered (stream, "Entry value of symbol @"); - gdb_print_host_address (exp->elts[elt].symbol, stream); - fprintf_filtered (stream, " (%s)", - exp->elts[elt].symbol->print_name ()); - elt += 2; - break; - case OP_LAST: - fprintf_filtered (stream, "History element %ld", - (long) exp->elts[elt].longconst); - elt += 2; - break; - case OP_REGISTER: - fprintf_filtered (stream, "Register $%s", &exp->elts[elt + 1].string); - elt += 3 + BYTES_TO_EXP_ELEM (exp->elts[elt].longconst + 1); - break; - case OP_INTERNALVAR: - fprintf_filtered (stream, "Internal var @"); - gdb_print_host_address (exp->elts[elt].internalvar, stream); - fprintf_filtered (stream, " (%s)", - internalvar_name (exp->elts[elt].internalvar)); - elt += 2; - break; - case OP_FUNCALL: - elt = dump_subexp_body_funcall (exp, stream, elt); - break; - case OP_ARRAY: - { - int lower, upper; - int i; - - lower = longest_to_int (exp->elts[elt].longconst); - upper = longest_to_int (exp->elts[elt + 1].longconst); - - fprintf_filtered (stream, "Bounds [%d:%d]", lower, upper); - elt += 3; - - for (i = 1; i <= upper - lower + 1; i++) - elt = dump_subexp (exp, stream, elt); - } - break; - case UNOP_DYNAMIC_CAST: - case UNOP_REINTERPRET_CAST: - case UNOP_CAST_TYPE: - case UNOP_MEMVAL_TYPE: - fprintf_filtered (stream, " ("); - elt = dump_subexp (exp, stream, elt); - fprintf_filtered (stream, ")"); - elt = dump_subexp (exp, stream, elt); - break; - case UNOP_MEMVAL: - case UNOP_CAST: - fprintf_filtered (stream, "Type @"); - gdb_print_host_address (exp->elts[elt].type, stream); - fprintf_filtered (stream, " ("); - type_print (exp->elts[elt].type, NULL, stream, 0); - fprintf_filtered (stream, ")"); - elt = dump_subexp (exp, stream, elt + 2); - break; - case OP_TYPE: - fprintf_filtered (stream, "Type @"); - gdb_print_host_address (exp->elts[elt].type, stream); - fprintf_filtered (stream, " ("); - type_print (exp->elts[elt].type, NULL, stream, 0); - fprintf_filtered (stream, ")"); - elt += 2; - break; - case OP_TYPEOF: - case OP_DECLTYPE: - fprintf_filtered (stream, "Typeof ("); - elt = dump_subexp (exp, stream, elt); - fprintf_filtered (stream, ")"); - break; - case OP_TYPEID: - fprintf_filtered (stream, "typeid ("); - elt = dump_subexp (exp, stream, elt); - fprintf_filtered (stream, ")"); - break; - case STRUCTOP_STRUCT: - case STRUCTOP_PTR: - { - char *elem_name; - int len; - - len = longest_to_int (exp->elts[elt].longconst); - elem_name = &exp->elts[elt + 1].string; - - fprintf_filtered (stream, "Element name: `%.*s'", len, elem_name); - elt = dump_subexp (exp, stream, elt + 3 + BYTES_TO_EXP_ELEM (len + 1)); - } - break; - case OP_SCOPE: - { - char *elem_name; - int len; - - fprintf_filtered (stream, "Type @"); - gdb_print_host_address (exp->elts[elt].type, stream); - fprintf_filtered (stream, " ("); - type_print (exp->elts[elt].type, NULL, stream, 0); - fprintf_filtered (stream, ") "); - - len = longest_to_int (exp->elts[elt + 1].longconst); - elem_name = &exp->elts[elt + 2].string; - - fprintf_filtered (stream, "Field name: `%.*s'", len, elem_name); - elt += 4 + BYTES_TO_EXP_ELEM (len + 1); - } - break; - - case OP_FUNC_STATIC_VAR: - { - int len = longest_to_int (exp->elts[elt].longconst); - const char *var_name = &exp->elts[elt + 1].string; - fprintf_filtered (stream, "Field name: `%.*s'", len, var_name); - elt += 3 + BYTES_TO_EXP_ELEM (len + 1); - } - break; - - case TYPE_INSTANCE: - { - type_instance_flags flags - = (type_instance_flag_value) longest_to_int (exp->elts[elt++].longconst); - LONGEST len = exp->elts[elt++].longconst; - fprintf_filtered (stream, "%s TypeInstance: ", plongest (len)); - while (len-- > 0) - { - fprintf_filtered (stream, "Type @"); - gdb_print_host_address (exp->elts[elt].type, stream); - fprintf_filtered (stream, " ("); - type_print (exp->elts[elt].type, NULL, stream, 0); - fprintf_filtered (stream, ")"); - elt++; - if (len > 0) - fputs_filtered (", ", stream); - } - - fprintf_filtered (stream, " Flags: %s (", hex_string (flags)); - bool space = false; - auto print_one = [&] (const char *mod) - { - if (space) - fputs_filtered (" ", stream); - space = true; - fprintf_filtered (stream, "%s", mod); - }; - if (flags & TYPE_INSTANCE_FLAG_CONST) - print_one ("const"); - if (flags & TYPE_INSTANCE_FLAG_VOLATILE) - print_one ("volatile"); - fprintf_filtered (stream, ")"); - - /* Ending LEN and ending TYPE_INSTANCE. */ - elt += 2; - elt = dump_subexp (exp, stream, elt); - } - break; - case OP_STRING: - { - LONGEST len = exp->elts[elt].longconst; - LONGEST type = exp->elts[elt + 1].longconst; - - fprintf_filtered (stream, "Language-specific string type: %s", - plongest (type)); - - /* Skip length. */ - elt += 1; - - /* Skip string content. */ - elt += BYTES_TO_EXP_ELEM (len); - - /* Skip length and ending OP_STRING. */ - elt += 2; - } - break; - case OP_RANGE: - { - enum range_flag range_flag; - - range_flag = (enum range_flag) - longest_to_int (exp->elts[elt].longconst); - elt += 2; - - if (range_flag & RANGE_HIGH_BOUND_EXCLUSIVE) - fputs_filtered ("Exclusive", stream); - fputs_filtered ("Range '", stream); - if (!(range_flag & RANGE_LOW_BOUND_DEFAULT)) - fputs_filtered ("EXP", stream); - fputs_filtered ("..", stream); - if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT)) - fputs_filtered ("EXP", stream); - if (range_flag & RANGE_HAS_STRIDE) - fputs_filtered (":EXP", stream); - fputs_filtered ("'", stream); - - if (!(range_flag & RANGE_LOW_BOUND_DEFAULT)) - elt = dump_subexp (exp, stream, elt); - if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT)) - elt = dump_subexp (exp, stream, elt); - if (range_flag & RANGE_HAS_STRIDE) - elt = dump_subexp (exp, stream, elt); - } - break; - - case OP_BOOL: - { - bool val = (bool) (exp->elts[elt].longconst); - fputs_filtered (val ? "TRUE" : "FALSE", stream); - elt += 2; - } - break; - - default: - case OP_NULL: - case MULTI_SUBSCRIPT: - case OP_COMPLEX: - case OP_M2_STRING: - case OP_THIS: - case OP_NAME: - fprintf_filtered (stream, "Unknown format"); - } - - return elt; -} - void dump_prefix_expression (struct expression *exp, struct ui_file *stream) { - int elt; - - if (exp->op != nullptr) - { - exp->op->dump (stream, 0); - return; - } - - fprintf_filtered (stream, "Dump of expression @ "); - gdb_print_host_address (exp, stream); - fputs_filtered (", after conversion to prefix form:\nExpression: `", stream); - - if (exp->op != nullptr) - { - exp->op->dump (stream, 0); - return; - } - - print_expression (exp, stream); - fprintf_filtered (stream, "'\n\tLanguage %s, %d elements, %ld bytes each.\n", - exp->language_defn->name (), exp->nelts, - (long) sizeof (union exp_element)); - fputs_filtered ("\n", stream); - - for (elt = 0; elt < exp->nelts;) - elt = dump_subexp (exp, stream, elt); - fputs_filtered ("\n", stream); + exp->op->dump (stream, 0); } namespace expr diff --git a/gdb/expression.h b/gdb/expression.h index 3abaf6e..31482be 100644 --- a/gdb/expression.h +++ b/gdb/expression.h @@ -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 diff --git a/gdb/f-lang.c b/gdb/f-lang.c index 465fea2..a4c210e 100644 --- a/gdb/f-lang.c +++ b/gdb/f-lang.c @@ -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. */ diff --git a/gdb/f-lang.h b/gdb/f-lang.h index 03b5910..1ccdd39 100644 --- a/gdb/f-lang.h +++ b/gdb/f-lang.h @@ -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. */ diff --git a/gdb/go-lang.c b/gdb/go-lang.c index 3af89b3..2a4fb1a 100644 --- a/gdb/go-lang.c +++ b/gdb/go-lang.c @@ -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 diff --git a/gdb/go-lang.h b/gdb/go-lang.h index 5d45c14..3495d98 100644 --- a/gdb/go-lang.h +++ b/gdb/go-lang.h @@ -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) */ diff --git a/gdb/language.c b/gdb/language.c index 0eff76e..f38d64f 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -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. */ diff --git a/gdb/language.h b/gdb/language.h index 4df09d8..5afb833 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -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. diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c index 36b15c3..fb813bd 100644 --- a/gdb/m2-lang.c +++ b/gdb/m2-lang.c @@ -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; diff --git a/gdb/m2-lang.h b/gdb/m2-lang.h index 2094142..89b9d18 100644 --- a/gdb/m2-lang.h +++ b/gdb/m2-lang.h @@ -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 */ diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c index 788fe0f..8e8cc05 100644 --- a/gdb/objc-lang.c +++ b/gdb/objc-lang.c @@ -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. */ diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c index b283be1..c168cd4 100644 --- a/gdb/opencl-lang.c +++ b/gdb/opencl-lang.c @@ -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. */ diff --git a/gdb/p-lang.c b/gdb/p-lang.c index 9654da1..1d8e940 100644 --- a/gdb/p-lang.c +++ b/gdb/p-lang.c @@ -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 diff --git a/gdb/p-lang.h b/gdb/p-lang.h index b93451d..95dca01 100644 --- a/gdb/p-lang.h +++ b/gdb/p-lang.h @@ -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. */ diff --git a/gdb/parse.c b/gdb/parse.c index d6f98bf..96dd5db 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -52,18 +52,6 @@ #include "gdbsupport/gdb_optional.h" #include "c-exp.h" -/* Standard set of definitions for printing, dumping, prefixifying, - * and evaluating expressions. */ - -const struct exp_descriptor exp_descriptor_standard = - { - print_subexp_standard, - operator_length_standard, - operator_check_standard, - dump_subexp_body_standard, - evaluate_subexp_standard - }; - static unsigned int expressiondebug = 0; static void show_expressiondebug (struct ui_file *file, int from_tty, @@ -84,18 +72,11 @@ show_parserdebug (struct ui_file *file, int from_tty, } -static int prefixify_subexp (struct expression *, struct expression *, int, - int, int); - static expression_up parse_exp_in_context (const char **, CORE_ADDR, const struct block *, int, - bool, int *, - innermost_block_tracker *, + bool, innermost_block_tracker *, expr_completion_state *); -static void increase_expout_size (struct expr_builder *ps, size_t lenelt); - - /* Documented at it's declaration. */ void @@ -114,297 +95,24 @@ innermost_block_tracker::update (const struct block *b, expr_builder::expr_builder (const struct language_defn *lang, struct gdbarch *gdbarch) - : expout_size (10), - expout (new expression (lang, gdbarch, expout_size)), - expout_ptr (0) + : expout (new expression (lang, gdbarch)) { } expression_up expr_builder::release () { - /* Record the actual number of expression elements, and then - reallocate the expression memory so that we free up any - excess elements. */ - - expout->nelts = expout_ptr; - expout->resize (expout_ptr); - return std::move (expout); } -expression::expression (const struct language_defn *lang, struct gdbarch *arch, - size_t n) +expression::expression (const struct language_defn *lang, struct gdbarch *arch) : language_defn (lang), - gdbarch (arch), - elts (nullptr) + gdbarch (arch) { - resize (n); } expression::~expression () { - xfree (elts); -} - -void -expression::resize (size_t n) -{ - elts = XRESIZEVAR (union exp_element, elts, EXP_ELEM_TO_BYTES (n)); -} - -/* This page contains the functions for adding data to the struct expression - being constructed. */ - -/* Add one element to the end of the expression. */ - -/* To avoid a bug in the Sun 4 compiler, we pass things that can fit into - a register through here. */ - -static void -write_exp_elt (struct expr_builder *ps, const union exp_element *expelt) -{ - if (ps->expout_ptr >= ps->expout_size) - { - ps->expout_size *= 2; - ps->expout->resize (ps->expout_size); - } - ps->expout->elts[ps->expout_ptr++] = *expelt; -} - -void -write_exp_elt_opcode (struct expr_builder *ps, enum exp_opcode expelt) -{ - union exp_element tmp; - - memset (&tmp, 0, sizeof (union exp_element)); - tmp.opcode = expelt; - write_exp_elt (ps, &tmp); -} - -void -write_exp_elt_sym (struct expr_builder *ps, struct symbol *expelt) -{ - union exp_element tmp; - - memset (&tmp, 0, sizeof (union exp_element)); - tmp.symbol = expelt; - write_exp_elt (ps, &tmp); -} - -static void -write_exp_elt_msym (struct expr_builder *ps, minimal_symbol *expelt) -{ - union exp_element tmp; - - memset (&tmp, 0, sizeof (union exp_element)); - tmp.msymbol = expelt; - write_exp_elt (ps, &tmp); -} - -void -write_exp_elt_block (struct expr_builder *ps, const struct block *b) -{ - union exp_element tmp; - - memset (&tmp, 0, sizeof (union exp_element)); - tmp.block = b; - write_exp_elt (ps, &tmp); -} - -void -write_exp_elt_objfile (struct expr_builder *ps, struct objfile *objfile) -{ - union exp_element tmp; - - memset (&tmp, 0, sizeof (union exp_element)); - tmp.objfile = objfile; - write_exp_elt (ps, &tmp); -} - -void -write_exp_elt_longcst (struct expr_builder *ps, LONGEST expelt) -{ - union exp_element tmp; - - memset (&tmp, 0, sizeof (union exp_element)); - tmp.longconst = expelt; - write_exp_elt (ps, &tmp); -} - -void -write_exp_elt_floatcst (struct expr_builder *ps, const gdb_byte expelt[16]) -{ - union exp_element tmp; - int index; - - for (index = 0; index < 16; index++) - tmp.floatconst[index] = expelt[index]; - - write_exp_elt (ps, &tmp); -} - -void -write_exp_elt_type (struct expr_builder *ps, struct type *expelt) -{ - union exp_element tmp; - - memset (&tmp, 0, sizeof (union exp_element)); - tmp.type = expelt; - write_exp_elt (ps, &tmp); -} - -void -write_exp_elt_intern (struct expr_builder *ps, struct internalvar *expelt) -{ - union exp_element tmp; - - memset (&tmp, 0, sizeof (union exp_element)); - tmp.internalvar = expelt; - write_exp_elt (ps, &tmp); -} - -/* Add a string constant to the end of the expression. - - String constants are stored by first writing an expression element - that contains the length of the string, then stuffing the string - constant itself into however many expression elements are needed - to hold it, and then writing another expression element that contains - the length of the string. I.e. an expression element at each end of - the string records the string length, so you can skip over the - expression elements containing the actual string bytes from either - end of the string. Note that this also allows gdb to handle - strings with embedded null bytes, as is required for some languages. - - Don't be fooled by the fact that the string is null byte terminated, - this is strictly for the convenience of debugging gdb itself. - Gdb does not depend up the string being null terminated, since the - actual length is recorded in expression elements at each end of the - string. The null byte is taken into consideration when computing how - many expression elements are required to hold the string constant, of - course. */ - - -void -write_exp_string (struct expr_builder *ps, struct stoken str) -{ - int len = str.length; - size_t lenelt; - char *strdata; - - /* Compute the number of expression elements required to hold the string - (including a null byte terminator), along with one expression element - at each end to record the actual string length (not including the - null byte terminator). */ - - lenelt = 2 + BYTES_TO_EXP_ELEM (len + 1); - - increase_expout_size (ps, lenelt); - - /* Write the leading length expression element (which advances the current - expression element index), then write the string constant followed by a - terminating null byte, and then write the trailing length expression - element. */ - - write_exp_elt_longcst (ps, (LONGEST) len); - strdata = (char *) &ps->expout->elts[ps->expout_ptr]; - memcpy (strdata, str.ptr, len); - *(strdata + len) = '\0'; - ps->expout_ptr += lenelt - 2; - write_exp_elt_longcst (ps, (LONGEST) len); -} - -/* Add a vector of string constants to the end of the expression. - - This adds an OP_STRING operation, but encodes the contents - differently from write_exp_string. The language is expected to - handle evaluation of this expression itself. - - After the usual OP_STRING header, TYPE is written into the - expression as a long constant. The interpretation of this field is - up to the language evaluator. - - Next, each string in VEC is written. The length is written as a - long constant, followed by the contents of the string. */ - -void -write_exp_string_vector (struct expr_builder *ps, int type, - struct stoken_vector *vec) -{ - int i, len; - size_t n_slots; - - /* Compute the size. We compute the size in number of slots to - avoid issues with string padding. */ - n_slots = 0; - for (i = 0; i < vec->len; ++i) - { - /* One slot for the length of this element, plus the number of - slots needed for this string. */ - n_slots += 1 + BYTES_TO_EXP_ELEM (vec->tokens[i].length); - } - - /* One more slot for the type of the string. */ - ++n_slots; - - /* Now compute a phony string length. */ - len = EXP_ELEM_TO_BYTES (n_slots) - 1; - - n_slots += 4; - increase_expout_size (ps, n_slots); - - write_exp_elt_opcode (ps, OP_STRING); - write_exp_elt_longcst (ps, len); - write_exp_elt_longcst (ps, type); - - for (i = 0; i < vec->len; ++i) - { - write_exp_elt_longcst (ps, vec->tokens[i].length); - memcpy (&ps->expout->elts[ps->expout_ptr], vec->tokens[i].ptr, - vec->tokens[i].length); - ps->expout_ptr += BYTES_TO_EXP_ELEM (vec->tokens[i].length); - } - - write_exp_elt_longcst (ps, len); - write_exp_elt_opcode (ps, OP_STRING); -} - -/* Add a bitstring constant to the end of the expression. - - Bitstring constants are stored by first writing an expression element - that contains the length of the bitstring (in bits), then stuffing the - bitstring constant itself into however many expression elements are - needed to hold it, and then writing another expression element that - contains the length of the bitstring. I.e. an expression element at - each end of the bitstring records the bitstring length, so you can skip - over the expression elements containing the actual bitstring bytes from - either end of the bitstring. */ - -void -write_exp_bitstring (struct expr_builder *ps, struct stoken str) -{ - int bits = str.length; /* length in bits */ - int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; - size_t lenelt; - char *strdata; - - /* Compute the number of expression elements required to hold the bitstring, - along with one expression element at each end to record the actual - bitstring length in bits. */ - - lenelt = 2 + BYTES_TO_EXP_ELEM (len); - - increase_expout_size (ps, lenelt); - - /* Write the leading length expression element (which advances the current - expression element index), then write the bitstring constant, and then - write the trailing length expression element. */ - - write_exp_elt_longcst (ps, (LONGEST) bits); - strdata = (char *) &ps->expout->elts[ps->expout_ptr]; - memcpy (strdata, str.ptr, len); - ps->expout_ptr += lenelt - 2; - write_exp_elt_longcst (ps, (LONGEST) bits); } /* Return the type of MSYMBOL, a minimal symbol of OBJFILE. If @@ -487,31 +195,6 @@ find_minsym_type_and_address (minimal_symbol *msymbol, } } -/* Add the appropriate elements for a minimal symbol to the end of - the expression. */ - -void -write_exp_msymbol (struct expr_builder *ps, - struct bound_minimal_symbol bound_msym) -{ - write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE); - write_exp_elt_objfile (ps, bound_msym.objfile); - write_exp_elt_msym (ps, bound_msym.minsym); - write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE); -} - -/* See parser-defs.h. */ - -void -parser_state::mark_struct_expression () -{ - gdb_assert (parse_completion - && (m_completion_state.expout_tag_completion_type - == TYPE_CODE_UNDEF) - && m_completion_state.expout_last_op == nullptr); - m_completion_state.expout_last_struct = expout_ptr; -} - /* See parser-defs.h. */ void @@ -519,8 +202,7 @@ parser_state::mark_struct_expression (expr::structop_base_operation *op) { gdb_assert (parse_completion && (m_completion_state.expout_tag_completion_type - == TYPE_CODE_UNDEF) - && m_completion_state.expout_last_struct == -1); + == TYPE_CODE_UNDEF)); m_completion_state.expout_last_op = op; } @@ -536,7 +218,6 @@ parser_state::mark_completion_tag (enum type_code tag, const char *ptr, && (m_completion_state.expout_tag_completion_type == TYPE_CODE_UNDEF) && m_completion_state.expout_completion_name == NULL - && m_completion_state.expout_last_struct == -1 && m_completion_state.expout_last_op == nullptr); gdb_assert (tag == TYPE_CODE_UNION || tag == TYPE_CODE_STRUCT @@ -673,151 +354,6 @@ handle_register: } -/* Recognize tokens that start with '$'. These include: - - $regname A native register name or a "standard - register name". - - $variable A convenience variable with a name chosen - by the user. - - $digits Value history with index <digits>, starting - from the first value which has index 1. - - $$digits Value history with index <digits> relative - to the last value. I.e. $$0 is the last - value, $$1 is the one previous to that, $$2 - is the one previous to $$1, etc. - - $ | $0 | $$0 The last value in the value history. - - $$ An abbreviation for the second to the last - value in the value history, I.e. $$1 */ - -void -write_dollar_variable (struct parser_state *ps, struct stoken str) -{ - struct block_symbol sym; - struct bound_minimal_symbol msym; - struct internalvar *isym = NULL; - std::string copy; - - /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1) - and $$digits (equivalent to $<-digits> if you could type that). */ - - int negate = 0; - int i = 1; - /* Double dollar means negate the number and add -1 as well. - Thus $$ alone means -1. */ - if (str.length >= 2 && str.ptr[1] == '$') - { - negate = 1; - i = 2; - } - if (i == str.length) - { - /* Just dollars (one or two). */ - i = -negate; - goto handle_last; - } - /* Is the rest of the token digits? */ - for (; i < str.length; i++) - if (!(str.ptr[i] >= '0' && str.ptr[i] <= '9')) - break; - if (i == str.length) - { - i = atoi (str.ptr + 1 + negate); - if (negate) - i = -i; - goto handle_last; - } - - /* Handle tokens that refer to machine registers: - $ followed by a register name. */ - i = user_reg_map_name_to_regnum (ps->gdbarch (), - str.ptr + 1, str.length - 1); - if (i >= 0) - goto handle_register; - - /* Any names starting with $ are probably debugger internal variables. */ - - copy = copy_name (str); - isym = lookup_only_internalvar (copy.c_str () + 1); - if (isym) - { - write_exp_elt_opcode (ps, OP_INTERNALVAR); - write_exp_elt_intern (ps, isym); - write_exp_elt_opcode (ps, OP_INTERNALVAR); - return; - } - - /* On some systems, such as HP-UX and hppa-linux, certain system routines - have names beginning with $ or $$. Check for those, first. */ - - sym = lookup_symbol (copy.c_str (), NULL, VAR_DOMAIN, NULL); - if (sym.symbol) - { - write_exp_elt_opcode (ps, OP_VAR_VALUE); - write_exp_elt_block (ps, sym.block); - write_exp_elt_sym (ps, sym.symbol); - write_exp_elt_opcode (ps, OP_VAR_VALUE); - return; - } - msym = lookup_bound_minimal_symbol (copy.c_str ()); - if (msym.minsym) - { - write_exp_msymbol (ps, msym); - return; - } - - /* Any other names are assumed to be debugger internal variables. */ - - write_exp_elt_opcode (ps, OP_INTERNALVAR); - write_exp_elt_intern (ps, create_internalvar (copy.c_str () + 1)); - write_exp_elt_opcode (ps, OP_INTERNALVAR); - return; -handle_last: - write_exp_elt_opcode (ps, OP_LAST); - write_exp_elt_longcst (ps, (LONGEST) i); - write_exp_elt_opcode (ps, OP_LAST); - return; -handle_register: - write_exp_elt_opcode (ps, OP_REGISTER); - str.length--; - str.ptr++; - write_exp_string (ps, str); - write_exp_elt_opcode (ps, OP_REGISTER); - ps->block_tracker->update (ps->expression_context_block, - INNERMOST_BLOCK_FOR_REGISTERS); - return; -} - -/* See parser-defs.h. */ - -void -write_exp_symbol_reference (struct parser_state *pstate, const char *name, - struct block_symbol sym) -{ - if (sym.symbol != nullptr) - { - if (symbol_read_needs_frame (sym.symbol)) - pstate->block_tracker->update (sym); - write_exp_elt_opcode (pstate, OP_VAR_VALUE); - write_exp_elt_block (pstate, sym.block); - write_exp_elt_sym (pstate, sym.symbol); - write_exp_elt_opcode (pstate, OP_VAR_VALUE); - } - else - { - struct bound_minimal_symbol msymbol = lookup_bound_minimal_symbol (name); - if (msymbol.minsym != NULL) - write_exp_msymbol (pstate, msymbol); - else if (!have_full_symbols () && !have_partial_symbols ()) - error (_("No symbol table is loaded. Use the \"file\" command.")); - else - error (_("No symbol \"%s\" in current context."), name); - } -} const char * find_template_name_end (const char *p) @@ -895,293 +431,6 @@ copy_name (struct stoken token) } -/* See comments on parser-defs.h. */ - -int -prefixify_expression (struct expression *expr, int last_struct) -{ - gdb_assert (expr->nelts > 0); - int len = EXP_ELEM_TO_BYTES (expr->nelts); - struct expression temp (expr->language_defn, expr->gdbarch, expr->nelts); - int inpos = expr->nelts, outpos = 0; - - /* Copy the original expression into temp. */ - memcpy (temp.elts, expr->elts, len); - - return prefixify_subexp (&temp, expr, inpos, outpos, last_struct); -} - -/* Return the number of exp_elements in the postfix subexpression - of EXPR whose operator is at index ENDPOS - 1 in EXPR. */ - -static int -length_of_subexp (struct expression *expr, int endpos) -{ - int oplen, args; - - operator_length (expr, endpos, &oplen, &args); - - while (args > 0) - { - oplen += length_of_subexp (expr, endpos - oplen); - args--; - } - - return oplen; -} - -/* Sets *OPLENP to the length of the operator whose (last) index is - ENDPOS - 1 in EXPR, and sets *ARGSP to the number of arguments that - operator takes. */ - -void -operator_length (const struct expression *expr, int endpos, int *oplenp, - int *argsp) -{ - expr->language_defn->expression_ops ()->operator_length (expr, endpos, - oplenp, argsp); -} - -/* Default value for operator_length in exp_descriptor vectors. */ - -void -operator_length_standard (const struct expression *expr, int endpos, - int *oplenp, int *argsp) -{ - int oplen = 1; - int args = 0; - enum range_flag range_flag; - int i; - - if (endpos < 1) - error (_("?error in operator_length_standard")); - - i = (int) expr->elts[endpos - 1].opcode; - - switch (i) - { - /* C++ */ - case OP_SCOPE: - oplen = longest_to_int (expr->elts[endpos - 2].longconst); - oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1); - break; - - case OP_LONG: - case OP_FLOAT: - case OP_VAR_VALUE: - case OP_VAR_MSYM_VALUE: - oplen = 4; - break; - - case OP_FUNC_STATIC_VAR: - oplen = longest_to_int (expr->elts[endpos - 2].longconst); - oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1); - args = 1; - break; - - case OP_TYPE: - case OP_BOOL: - case OP_LAST: - case OP_INTERNALVAR: - case OP_VAR_ENTRY_VALUE: - oplen = 3; - break; - - case OP_COMPLEX: - oplen = 3; - args = 2; - break; - - case OP_FUNCALL: - oplen = 3; - args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); - break; - - case TYPE_INSTANCE: - oplen = 5 + longest_to_int (expr->elts[endpos - 2].longconst); - args = 1; - break; - - case OP_OBJC_MSGCALL: /* Objective C message (method) call. */ - oplen = 4; - args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); - break; - - case UNOP_MAX: - case UNOP_MIN: - oplen = 3; - break; - - case UNOP_CAST_TYPE: - case UNOP_DYNAMIC_CAST: - case UNOP_REINTERPRET_CAST: - case UNOP_MEMVAL_TYPE: - oplen = 1; - args = 2; - break; - - case BINOP_VAL: - case UNOP_CAST: - case UNOP_MEMVAL: - oplen = 3; - args = 1; - break; - - case UNOP_ABS: - case UNOP_CAP: - case UNOP_CHR: - case UNOP_FLOAT: - case UNOP_HIGH: - case UNOP_ODD: - case UNOP_ORD: - case UNOP_TRUNC: - case OP_TYPEOF: - case OP_DECLTYPE: - case OP_TYPEID: - oplen = 1; - args = 1; - break; - - case OP_ADL_FUNC: - oplen = longest_to_int (expr->elts[endpos - 2].longconst); - oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1); - oplen++; - oplen++; - break; - - case STRUCTOP_STRUCT: - case STRUCTOP_PTR: - args = 1; - /* fall through */ - case OP_REGISTER: - case OP_M2_STRING: - case OP_STRING: - case OP_OBJC_NSSTRING: /* Objective C Foundation Class - NSString constant. */ - case OP_OBJC_SELECTOR: /* Objective C "@selector" pseudo-op. */ - case OP_NAME: - oplen = longest_to_int (expr->elts[endpos - 2].longconst); - oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1); - break; - - case OP_ARRAY: - oplen = 4; - args = longest_to_int (expr->elts[endpos - 2].longconst); - args -= longest_to_int (expr->elts[endpos - 3].longconst); - args += 1; - break; - - case TERNOP_COND: - case TERNOP_SLICE: - args = 3; - break; - - /* Modula-2 */ - case MULTI_SUBSCRIPT: - oplen = 3; - args = 1 + longest_to_int (expr->elts[endpos - 2].longconst); - break; - - case BINOP_ASSIGN_MODIFY: - oplen = 3; - args = 2; - break; - - /* C++ */ - case OP_THIS: - oplen = 2; - break; - - case OP_RANGE: - oplen = 3; - range_flag = (enum range_flag) - longest_to_int (expr->elts[endpos - 2].longconst); - - /* Assume the range has 2 arguments (low bound and high bound), then - reduce the argument count if any bounds are set to default. */ - args = 2; - if (range_flag & RANGE_HAS_STRIDE) - ++args; - if (range_flag & RANGE_LOW_BOUND_DEFAULT) - --args; - if (range_flag & RANGE_HIGH_BOUND_DEFAULT) - --args; - - break; - - default: - args = 1 + (i < (int) BINOP_END); - } - - *oplenp = oplen; - *argsp = args; -} - -/* Copy the subexpression ending just before index INEND in INEXPR - into OUTEXPR, starting at index OUTBEG. - In the process, convert it from suffix to prefix form. - If LAST_STRUCT is -1, then this function always returns -1. - Otherwise, it returns the index of the subexpression which is the - left-hand-side of the expression at LAST_STRUCT. */ - -static int -prefixify_subexp (struct expression *inexpr, - struct expression *outexpr, int inend, int outbeg, - int last_struct) -{ - int oplen; - int args; - int i; - int *arglens; - int result = -1; - - operator_length (inexpr, inend, &oplen, &args); - - /* Copy the final operator itself, from the end of the input - to the beginning of the output. */ - inend -= oplen; - memcpy (&outexpr->elts[outbeg], &inexpr->elts[inend], - EXP_ELEM_TO_BYTES (oplen)); - outbeg += oplen; - - if (last_struct == inend) - result = outbeg - oplen; - - /* Find the lengths of the arg subexpressions. */ - arglens = (int *) alloca (args * sizeof (int)); - for (i = args - 1; i >= 0; i--) - { - oplen = length_of_subexp (inexpr, inend); - arglens[i] = oplen; - inend -= oplen; - } - - /* Now copy each subexpression, preserving the order of - the subexpressions, but prefixifying each one. - In this loop, inend starts at the beginning of - the expression this level is working on - and marches forward over the arguments. - outbeg does similarly in the output. */ - for (i = 0; i < args; i++) - { - int r; - - oplen = arglens[i]; - inend += oplen; - r = prefixify_subexp (inexpr, outexpr, inend, outbeg, last_struct); - if (r != -1) - { - /* Return immediately. We probably have only parsed a - partial expression, so we don't want to try to reverse - the other operands. */ - return r; - } - outbeg += oplen; - } - - return result; -} - /* Read an expression from the string *STRINGPTR points to, parse it, and return a pointer to a struct expression that we malloc. Use block BLOCK as the lexical context for variable names; @@ -1196,21 +445,17 @@ expression_up parse_exp_1 (const char **stringptr, CORE_ADDR pc, const struct block *block, int comma, innermost_block_tracker *tracker) { - return parse_exp_in_context (stringptr, pc, block, comma, false, NULL, + return parse_exp_in_context (stringptr, pc, block, comma, false, tracker, nullptr); } /* As for parse_exp_1, except that if VOID_CONTEXT_P, then - no value is expected from the expression. - OUT_SUBEXP is set when attempting to complete a field name; in this - case it is set to the index of the subexpression on the - left-hand-side of the struct op. If not doing such completion, it - is left untouched. */ + no value is expected from the expression. */ static expression_up parse_exp_in_context (const char **stringptr, CORE_ADDR pc, const struct block *block, - int comma, bool void_context_p, int *out_subexp, + int comma, bool void_context_p, innermost_block_tracker *tracker, expr_completion_state *cstate) { @@ -1294,33 +539,12 @@ parse_exp_in_context (const char **stringptr, CORE_ADDR pc, /* If parsing for completion, allow this to succeed; but if no expression elements have been written, then there's nothing to do, so fail. */ - if (! ps.parse_completion - || (ps.expout->op == nullptr && ps.expout_ptr == 0)) + if (! ps.parse_completion || ps.expout->op == nullptr) throw; } - /* We have to operate on an "expression *", due to la_post_parser, - which explains this funny-looking double release. */ expression_up result = ps.release (); - - /* Convert expression from postfix form as generated by yacc - parser, to a prefix form. */ - - if (expressiondebug) - dump_raw_expression (result.get (), gdb_stdlog, - "before conversion to prefix form"); - - if (result->op == nullptr) - { - int subexp = prefixify_expression (result.get (), - ps.m_completion_state.expout_last_struct); - if (out_subexp) - *out_subexp = subexp; - - lang->post_parser (&result, &ps); - } - else - result->op->set_outermost (); + result->op->set_outermost (); if (expressiondebug) dump_prefix_expression (result.get (), gdb_stdlog); @@ -1343,7 +567,7 @@ parse_expression (const char *string, innermost_block_tracker *tracker, bool void_context_p) { expression_up exp = parse_exp_in_context (&string, 0, nullptr, 0, - void_context_p, nullptr, + void_context_p, tracker, nullptr); if (*string) error (_("Junk after end of expression.")); @@ -1379,14 +603,11 @@ parse_expression_for_completion (const char *string, enum type_code *code) { expression_up exp; - struct value *val; - int subexp; expr_completion_state cstate; try { - exp = parse_exp_in_context (&string, 0, 0, 0, false, &subexp, - nullptr, &cstate); + exp = parse_exp_in_context (&string, 0, 0, 0, false, nullptr, &cstate); } catch (const gdb_exception_error &except) { @@ -1403,30 +624,13 @@ parse_expression_for_completion (const char *string, return NULL; } - if (cstate.expout_last_op != nullptr) - { - expr::structop_base_operation *op = cstate.expout_last_op; - const std::string &fld = op->get_string (); - *name = make_unique_xstrdup (fld.c_str ()); - return value_type (op->evaluate_lhs (exp.get ())); - } + if (cstate.expout_last_op == nullptr) + return nullptr; - if (cstate.expout_last_struct == -1) - return NULL; - - const char *fieldname = extract_field_op (exp.get (), &subexp); - if (fieldname == NULL) - { - name->reset (); - return NULL; - } - - name->reset (xstrdup (fieldname)); - /* This might throw an exception. If so, we want to let it - propagate. */ - val = evaluate_subexpression_type (exp.get (), subexp); - - return value_type (val); + expr::structop_base_operation *op = cstate.expout_last_op; + const std::string &fld = op->get_string (); + *name = make_unique_xstrdup (fld.c_str ()); + return value_type (op->evaluate_lhs (exp.get ())); } /* Parse floating point value P of length LEN. @@ -1461,132 +665,6 @@ parser_fprintf (FILE *x, const char *y, ...) va_end (args); } -/* Implementation of the exp_descriptor method operator_check. */ - -int -operator_check_standard (struct expression *exp, int pos, - int (*objfile_func) (struct objfile *objfile, - void *data), - void *data) -{ - const union exp_element *const elts = exp->elts; - struct type *type = NULL; - struct objfile *objfile = NULL; - - /* Extended operators should have been already handled by exp_descriptor - iterate method of its specific language. */ - gdb_assert (elts[pos].opcode < OP_EXTENDED0); - - /* Track the callers of write_exp_elt_type for this table. */ - - switch (elts[pos].opcode) - { - case BINOP_VAL: - case OP_COMPLEX: - case OP_FLOAT: - case OP_LONG: - case OP_SCOPE: - case OP_TYPE: - case UNOP_CAST: - case UNOP_MAX: - case UNOP_MEMVAL: - case UNOP_MIN: - type = elts[pos + 1].type; - break; - - case TYPE_INSTANCE: - { - LONGEST arg, nargs = elts[pos + 2].longconst; - - for (arg = 0; arg < nargs; arg++) - { - struct type *inst_type = elts[pos + 3 + arg].type; - struct objfile *inst_objfile = inst_type->objfile_owner (); - - if (inst_objfile && (*objfile_func) (inst_objfile, data)) - return 1; - } - } - break; - - case OP_VAR_VALUE: - { - const struct block *const block = elts[pos + 1].block; - const struct symbol *const symbol = elts[pos + 2].symbol; - - /* Check objfile where the variable itself is placed. */ - if ((*objfile_func) (symbol_objfile (symbol), data)) - return 1; - - /* Check objfile where is placed the code touching the variable. */ - objfile = block_objfile (block); - - type = SYMBOL_TYPE (symbol); - } - break; - case OP_VAR_MSYM_VALUE: - objfile = elts[pos + 1].objfile; - break; - } - - /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL. */ - - if (type != nullptr && type->objfile_owner () != nullptr - && objfile_func (type->objfile_owner (), data)) - return 1; - - if (objfile && (*objfile_func) (objfile, data)) - return 1; - - return 0; -} - -/* Call OBJFILE_FUNC for any objfile found being referenced by EXP. - OBJFILE_FUNC is never called with NULL OBJFILE. OBJFILE_FUNC get - passed an arbitrary caller supplied DATA pointer. If OBJFILE_FUNC - returns non-zero value then (any other) non-zero value is immediately - returned to the caller. Otherwise zero is returned after iterating - through whole EXP. */ - -static int -exp_iterate (struct expression *exp, - int (*objfile_func) (struct objfile *objfile, void *data), - void *data) -{ - int endpos; - - for (endpos = exp->nelts; endpos > 0; ) - { - int pos, args, oplen = 0; - - operator_length (exp, endpos, &oplen, &args); - gdb_assert (oplen > 0); - - pos = endpos - oplen; - if (exp->language_defn->expression_ops ()->operator_check (exp, pos, - objfile_func, - data)) - return 1; - - endpos = pos; - } - - return 0; -} - -/* Helper for exp_uses_objfile. */ - -static int -exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp) -{ - struct objfile *objfile = (struct objfile *) objfile_voidp; - - if (exp_objfile->separate_debug_objfile_backlink) - exp_objfile = exp_objfile->separate_debug_objfile_backlink; - - return exp_objfile == objfile; -} - /* Return 1 if EXP uses OBJFILE (and will become dangling when OBJFILE is unloaded), otherwise return 0. OBJFILE must not be a separate debug info file. */ @@ -1596,25 +674,7 @@ exp_uses_objfile (struct expression *exp, struct objfile *objfile) { gdb_assert (objfile->separate_debug_objfile_backlink == NULL); - if (exp->op != nullptr) - return exp->op->uses_objfile (objfile); - - return exp_iterate (exp, exp_uses_objfile_iter, objfile); -} - -/* Reallocate the `expout' pointer inside PS so that it can accommodate - at least LENELT expression elements. This function does nothing if - there is enough room for the elements. */ - -static void -increase_expout_size (struct expr_builder *ps, size_t lenelt) -{ - if ((ps->expout_ptr + lenelt) >= ps->expout_size) - { - ps->expout_size = std::max (ps->expout_size * 2, - ps->expout_ptr + lenelt + 10); - ps->expout->resize (ps->expout_size); - } + return exp->op->uses_objfile (objfile); } void _initialize_parse (); diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index 6932559..3e81e0b 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -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. */ diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index 72f0283..f1ba165 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -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) diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 235f2de..2a06aea 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -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: diff --git a/gdb/rust-lang.h b/gdb/rust-lang.h index ec97cac..ea3f974 100644 --- a/gdb/rust-lang.h +++ b/gdb/rust-lang.h @@ -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. diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c index 264d912..5995c28 100644 --- a/gdb/stap-probe.c +++ b/gdb/stap-probe.c @@ -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; diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 101c526..bf8a63c 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -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, diff --git a/gdb/value.c b/gdb/value.c index 89b612e..df0e5c1 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -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) diff --git a/gdb/value.h b/gdb/value.h index 7f72938..21df6c2 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -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); |