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/eval.c | |
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/eval.c')
-rw-r--r-- | gdb/eval.c | 1624 |
1 files changed, 7 insertions, 1617 deletions
@@ -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 (); } |