From aa1da9ed50fba2474438f83e6da577bb01ed4613 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 8 Mar 2021 07:27:57 -0700 Subject: [PATCH] Remove now-unused Rust evaluator code Now that the Rust parser has switched to the new style, there is no need for the old Rust evaluation code. gdb/ChangeLog 2021-03-08 Tom Tromey * rust-lang.h (class rust_language) : Remove. * rust-lang.c (rust_evaluate_funcall): Remove. (rust_range, rust_subscript, eval_op_rust_complement): Don't use EVAL_SKIP. (rust_evaluate_subexp): Remove. (rust_aggregate_operation::evaluate): Don't use EVAL_SKIP. (rust_operator_length, rust_dump_subexp_body, rust_print_subexp) (rust_operator_check, rust_language::exp_descriptor_tab): Remove. --- gdb/ChangeLog | 12 ++ gdb/rust-lang.c | 507 +----------------------------------------------- gdb/rust-lang.h | 10 - 3 files changed, 13 insertions(+), 516 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5ecd54e7a06..9cafd0ce141 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2021-03-08 Tom Tromey + + * rust-lang.h (class rust_language) : Remove. + * rust-lang.c (rust_evaluate_funcall): Remove. + (rust_range, rust_subscript, eval_op_rust_complement): Don't use + EVAL_SKIP. + (rust_evaluate_subexp): Remove. + (rust_aggregate_operation::evaluate): Don't use EVAL_SKIP. + (rust_operator_length, rust_dump_subexp_body, rust_print_subexp) + (rust_operator_check, rust_language::exp_descriptor_tab): Remove. + 2021-03-08 Tom Tromey * ada-exp.y: Create operations. diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index e0b949b056a..a57ee988668 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -963,82 +963,6 @@ rust_slice_type (const char *name, struct type *elt_type, -/* A helper for rust_evaluate_subexp that handles OP_FUNCALL. */ - -static struct value * -rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside) -{ - int i; - int num_args = exp->elts[*pos + 1].longconst; - const char *method; - struct value *function, *result, *arg0; - struct type *type, *fn_type; - const struct block *block; - struct block_symbol sym; - - /* For an ordinary function call we can simply defer to the - generic implementation. */ - if (exp->elts[*pos + 3].opcode != STRUCTOP_STRUCT) - return evaluate_subexp_standard (NULL, exp, pos, noside); - - /* Skip over the OP_FUNCALL and the STRUCTOP_STRUCT. */ - *pos += 4; - method = &exp->elts[*pos + 1].string; - *pos += 3 + BYTES_TO_EXP_ELEM (exp->elts[*pos].longconst + 1); - - /* Evaluate the argument to STRUCTOP_STRUCT, then find its - type in order to look up the method. */ - arg0 = evaluate_subexp (nullptr, exp, pos, noside); - - if (noside == EVAL_SKIP) - { - for (i = 0; i < num_args; ++i) - evaluate_subexp (nullptr, exp, pos, noside); - return arg0; - } - - std::vector args (num_args + 1); - args[0] = arg0; - - /* We don't yet implement real Deref semantics. */ - while (value_type (args[0])->code () == TYPE_CODE_PTR) - args[0] = value_ind (args[0]); - - type = value_type (args[0]); - if ((type->code () != TYPE_CODE_STRUCT - && type->code () != TYPE_CODE_UNION - && type->code () != TYPE_CODE_ENUM) - || rust_tuple_type_p (type)) - error (_("Method calls only supported on struct or enum types")); - if (type->name () == NULL) - error (_("Method call on nameless type")); - - std::string name = std::string (type->name ()) + "::" + method; - - block = get_selected_block (0); - sym = lookup_symbol (name.c_str (), block, VAR_DOMAIN, NULL); - if (sym.symbol == NULL) - error (_("Could not find function named '%s'"), name.c_str ()); - - fn_type = SYMBOL_TYPE (sym.symbol); - if (fn_type->num_fields () == 0) - error (_("Function '%s' takes no arguments"), name.c_str ()); - - if (fn_type->field (0).type ()->code () == TYPE_CODE_PTR) - args[0] = value_addr (args[0]); - - function = address_of_variable (sym.symbol, block); - - for (i = 0; i < num_args; ++i) - args[i + 1] = evaluate_subexp (nullptr, exp, pos, noside); - - if (noside == EVAL_AVOID_SIDE_EFFECTS) - result = value_zero (TYPE_TARGET_TYPE (fn_type), not_lval); - else - result = call_function_by_hand (function, NULL, args); - return result; -} - /* A helper for rust_evaluate_subexp that handles OP_RANGE. */ struct value * @@ -1055,9 +979,6 @@ rust_range (struct type *expect_type, struct expression *exp, bool inclusive = !(kind & RANGE_HIGH_BOUND_EXCLUSIVE); - if (noside == EVAL_SKIP) - return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1); - if (low == NULL) { if (high == NULL) @@ -1181,9 +1102,6 @@ rust_subscript (struct type *expect_type, struct expression *exp, LONGEST high = 0; int want_slice = 0; - if (noside == EVAL_SKIP) - return lhs; - rhstype = check_typedef (value_type (rhs)); if (rust_range_type_p (rhstype)) { @@ -1347,11 +1265,6 @@ eval_op_rust_complement (struct type *expect_type, struct expression *exp, enum exp_opcode opcode, struct value *value) { - if (noside == EVAL_SKIP) - { - /* Preserving the type is enough. */ - return value; - } if (value_type (value)->code () == TYPE_CODE_BOOL) return value_from_longest (value_type (value), value_logical_not (value)); return value_complement (value); @@ -1502,204 +1415,6 @@ eval_op_rust_structop (struct type *expect_type, struct expression *exp, return result; } -/* evaluate_exp implementation for Rust. */ - -static struct value * -rust_evaluate_subexp (struct type *expect_type, struct expression *exp, - int *pos, enum noside noside) -{ - struct value *result; - enum exp_opcode op = exp->elts[*pos].opcode; - - switch (op) - { - case UNOP_IND: - { - if (noside != EVAL_NORMAL) - result = evaluate_subexp_standard (expect_type, exp, pos, noside); - else - { - ++*pos; - struct value *value = evaluate_subexp (expect_type, exp, pos, - noside); - result = eval_op_rust_ind (expect_type, exp, noside, op, value); - } - } - break; - - case UNOP_COMPLEMENT: - { - struct value *value; - - ++*pos; - value = evaluate_subexp (nullptr, exp, pos, noside); - result = eval_op_rust_complement (expect_type, exp, noside, op, value); - } - break; - - case BINOP_SUBSCRIPT: - { - ++*pos; - struct value *lhs = evaluate_subexp (nullptr, exp, pos, noside); - struct value *rhs = evaluate_subexp (nullptr, exp, pos, noside); - result = rust_subscript (expect_type, exp, noside, false, lhs, rhs); - } - break; - - case OP_FUNCALL: - result = rust_evaluate_funcall (exp, pos, noside); - break; - - case OP_AGGREGATE: - { - int pc = (*pos)++; - struct type *type = exp->elts[pc + 1].type; - int arglen = longest_to_int (exp->elts[pc + 2].longconst); - int i; - CORE_ADDR addr = 0; - struct value *addrval = NULL; - - *pos += 3; - - if (noside == EVAL_NORMAL) - { - addrval = value_allocate_space_in_inferior (TYPE_LENGTH (type)); - addr = value_as_long (addrval); - result = value_at_lazy (type, addr); - } - - if (arglen > 0 && exp->elts[*pos].opcode == OP_OTHERS) - { - struct value *init; - - ++*pos; - init = rust_evaluate_subexp (NULL, exp, pos, noside); - if (noside == EVAL_NORMAL) - { - /* This isn't quite right but will do for the time - being, seeing that we can't implement the Copy - trait anyway. */ - value_assign (result, init); - } - - --arglen; - } - - gdb_assert (arglen % 2 == 0); - for (i = 0; i < arglen; i += 2) - { - int len; - const char *fieldname; - struct value *value, *field; - - gdb_assert (exp->elts[*pos].opcode == OP_NAME); - ++*pos; - len = longest_to_int (exp->elts[*pos].longconst); - ++*pos; - fieldname = &exp->elts[*pos].string; - *pos += 2 + BYTES_TO_EXP_ELEM (len + 1); - - value = rust_evaluate_subexp (NULL, exp, pos, noside); - if (noside == EVAL_NORMAL) - { - field = value_struct_elt (&result, NULL, fieldname, NULL, - "structure"); - value_assign (field, value); - } - } - - if (noside == EVAL_SKIP) - return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, - 1); - else if (noside == EVAL_AVOID_SIDE_EFFECTS) - result = allocate_value (type); - else - result = value_at_lazy (type, addr); - } - break; - - case OP_RUST_ARRAY: - { - (*pos)++; - struct value *elt; - struct value *ncopies; - - elt = rust_evaluate_subexp (NULL, exp, pos, noside); - ncopies = rust_evaluate_subexp (NULL, exp, pos, noside); - return eval_op_rust_array (expect_type, exp, noside, op, elt, ncopies); - } - break; - - case STRUCTOP_ANONYMOUS: - { - /* Anonymous field access, i.e. foo.1. */ - struct value *lhs; - int pc, field_number; - - pc = (*pos)++; - field_number = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 2; - lhs = evaluate_subexp (nullptr, exp, pos, noside); - - return eval_op_rust_struct_anon (expect_type, exp, noside, - field_number, lhs); - } - break; - - case STRUCTOP_STRUCT: - { - struct value *lhs; - int tem, pc; - - pc = (*pos)++; - tem = longest_to_int (exp->elts[pc + 1].longconst); - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); - lhs = evaluate_subexp (nullptr, exp, pos, noside); - - const char *field_name = &exp->elts[pc + 2].string; - return eval_op_rust_structop (expect_type, exp, noside, lhs, - field_name); - } - break; - - case OP_RANGE: - { - struct value *low = NULL, *high = NULL; - auto kind - = (enum range_flag) longest_to_int (exp->elts[*pos + 1].longconst); - *pos += 3; - - if (!(kind & RANGE_LOW_BOUND_DEFAULT)) - low = evaluate_subexp (nullptr, exp, pos, noside); - if (!(kind & RANGE_HIGH_BOUND_DEFAULT)) - high = evaluate_subexp (nullptr, exp, pos, noside); - - result = rust_range (expect_type, exp, noside, kind, low, high); - } - break; - - case UNOP_ADDR: - /* We might have &array[range], in which case we need to make a - slice. */ - if (exp->elts[*pos + 1].opcode == BINOP_SUBSCRIPT) - { - ++*pos; - ++*pos; - struct value *lhs = evaluate_subexp (nullptr, exp, pos, noside); - struct value *rhs = evaluate_subexp (nullptr, exp, pos, noside); - - result = rust_subscript (expect_type, exp, noside, true, lhs, rhs); - break; - } - /* Fall through. */ - default: - result = evaluate_subexp_standard (expect_type, exp, pos, noside); - break; - } - - return result; -} - namespace expr { @@ -1746,9 +1461,7 @@ rust_aggregate_operation::evaluate (struct type *expect_type, } } - if (noside == EVAL_SKIP) - result = value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1); - else if (noside == EVAL_AVOID_SIDE_EFFECTS) + if (noside == EVAL_AVOID_SIDE_EFFECTS) result = allocate_value (type); else result = value_at_lazy (type, addr); @@ -1808,226 +1521,8 @@ rust_structop::evaluate_funcall (struct type *expect_type, } -/* operator_length implementation for Rust. */ - -static void -rust_operator_length (const struct expression *exp, int pc, int *oplenp, - int *argsp) -{ - int oplen = 1; - int args = 0; - - switch (exp->elts[pc - 1].opcode) - { - case OP_AGGREGATE: - /* We handle aggregate as a type and argument count. The first - argument might be OP_OTHERS. After that the arguments - alternate: first an OP_NAME, then an expression. */ - oplen = 4; - args = longest_to_int (exp->elts[pc - 2].longconst); - break; - - case OP_OTHERS: - oplen = 1; - args = 1; - break; - - case STRUCTOP_ANONYMOUS: - oplen = 3; - args = 1; - break; - - case OP_RUST_ARRAY: - oplen = 1; - args = 2; - break; - - default: - operator_length_standard (exp, pc, oplenp, argsp); - return; - } - - *oplenp = oplen; - *argsp = args; -} - -/* dump_subexp_body implementation for Rust. */ - -static int -rust_dump_subexp_body (struct expression *exp, struct ui_file *stream, - int elt) -{ - switch (exp->elts[elt].opcode) - { - case OP_AGGREGATE: - { - int length = longest_to_int (exp->elts[elt + 2].longconst); - int i; - - fprintf_filtered (stream, "Type @"); - gdb_print_host_address (exp->elts[elt + 1].type, stream); - fprintf_filtered (stream, " ("); - type_print (exp->elts[elt + 1].type, NULL, stream, 0); - fprintf_filtered (stream, "), length %d", length); - - elt += 4; - for (i = 0; i < length; ++i) - elt = dump_subexp (exp, stream, elt); - } - break; - - case OP_STRING: - case OP_NAME: - { - LONGEST len = exp->elts[elt + 1].longconst; - - fprintf_filtered (stream, "%s: %s", - (exp->elts[elt].opcode == OP_STRING - ? "string" : "name"), - &exp->elts[elt + 2].string); - elt += 4 + BYTES_TO_EXP_ELEM (len + 1); - } - break; - - case OP_OTHERS: - elt = dump_subexp (exp, stream, elt + 1); - break; - - case STRUCTOP_ANONYMOUS: - { - int field_number; - - field_number = longest_to_int (exp->elts[elt + 1].longconst); - - fprintf_filtered (stream, "Field number: %d", field_number); - elt = dump_subexp (exp, stream, elt + 3); - } - break; - - case OP_RUST_ARRAY: - ++elt; - break; - - default: - elt = dump_subexp_body_standard (exp, stream, elt); - break; - } - - return elt; -} - -/* print_subexp implementation for Rust. */ - -static void -rust_print_subexp (struct expression *exp, int *pos, struct ui_file *stream, - enum precedence prec) -{ - switch (exp->elts[*pos].opcode) - { - case OP_AGGREGATE: - { - int length = longest_to_int (exp->elts[*pos + 2].longconst); - int i; - - type_print (exp->elts[*pos + 1].type, "", stream, 0); - fputs_filtered (" { ", stream); - - *pos += 4; - for (i = 0; i < length; ++i) - { - rust_print_subexp (exp, pos, stream, prec); - fputs_filtered (", ", stream); - } - fputs_filtered (" }", stream); - } - break; - - case OP_NAME: - { - LONGEST len = exp->elts[*pos + 1].longconst; - - fputs_filtered (&exp->elts[*pos + 2].string, stream); - *pos += 4 + BYTES_TO_EXP_ELEM (len + 1); - } - break; - - case OP_OTHERS: - { - fputs_filtered ("<> (", stream); - ++*pos; - rust_print_subexp (exp, pos, stream, prec); - fputs_filtered (")", stream); - } - break; - - case STRUCTOP_ANONYMOUS: - { - int tem = longest_to_int (exp->elts[*pos + 1].longconst); - - (*pos) += 3; - print_subexp (exp, pos, stream, PREC_SUFFIX); - fprintf_filtered (stream, ".%d", tem); - } - break; - - case OP_RUST_ARRAY: - ++*pos; - fprintf_filtered (stream, "["); - rust_print_subexp (exp, pos, stream, prec); - fprintf_filtered (stream, "; "); - rust_print_subexp (exp, pos, stream, prec); - fprintf_filtered (stream, "]"); - break; - - default: - print_subexp_standard (exp, pos, stream, prec); - break; - } -} - -/* operator_check implementation for Rust. */ - -static int -rust_operator_check (struct expression *exp, int pos, - int (*objfile_func) (struct objfile *objfile, - void *data), - void *data) -{ - switch (exp->elts[pos].opcode) - { - case OP_AGGREGATE: - { - struct type *type = exp->elts[pos + 1].type; - struct objfile *objfile = type->objfile_owner (); - - if (objfile != NULL && (*objfile_func) (objfile, data)) - return 1; - } - break; - - case OP_OTHERS: - case OP_NAME: - case OP_RUST_ARRAY: - break; - - default: - return operator_check_standard (exp, pos, objfile_func, data); - } - - return 0; -} - -const struct exp_descriptor rust_language::exp_descriptor_tab = -{ - rust_print_subexp, - rust_operator_length, - rust_operator_check, - rust_dump_subexp_body, - rust_evaluate_subexp -}; - /* See language.h. */ void diff --git a/gdb/rust-lang.h b/gdb/rust-lang.h index fb27f60eeab..ec97cac3dae 100644 --- a/gdb/rust-lang.h +++ b/gdb/rust-lang.h @@ -211,21 +211,11 @@ public: /* See language.h. */ - const struct exp_descriptor *expression_ops () const override - { return &exp_descriptor_tab; } - - /* See language.h. */ - const struct op_print *opcode_print_table () const override { return c_op_print_tab; } private: - /* Table of expression handling functions for use by EXPRESSION_OPS - member function. */ - - static const struct exp_descriptor exp_descriptor_tab; - /* Helper for value_print_inner, arguments are as for that function. Prints structs and untagged unions. */ -- 2.30.2