X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Feval.c;h=bcdb78f05bcfedc8f832073b96e129a5f9a8e414;hb=14aa4ee440f85a0e4d86b7adb50c93bbf0b7fc5b;hp=4601c92ed5f4c1751c3ad2b9c0e66515acdc10bc;hpb=55bdbff857f80da9e3464968f1ada2be3484fcf9;p=binutils-gdb.git diff --git a/gdb/eval.c b/gdb/eval.c index 4601c92ed5f..bcdb78f05bc 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -41,30 +41,9 @@ #include "typeprint.h" #include #include "expop.h" +#include "c-exp.h" +#include "inferior.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. */ @@ -114,13 +93,12 @@ struct value * expression::evaluate (struct type *expect_type, enum noside noside) { gdb::optional stack_temporaries; - if (target_has_execution () + if (target_has_execution () && inferior_ptid != null_ptid && language_defn->la_language == language_cplus && !thread_stack_temporaries_enabled_p (inferior_thread ())) stack_temporaries.emplace (inferior_thread ()); - int pos = 0; - struct value *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 ())) @@ -146,15 +124,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) -{ - 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 @@ -178,8 +147,9 @@ 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, struct value **valp, - struct value **resultp, +fetch_subexp_value (struct expression *exp, + expr::operation *op, + struct value **valp, struct value **resultp, std::vector *val_chain, bool preserve_errors) { @@ -197,7 +167,7 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, try { - result = evaluate_subexp (nullptr, exp, pc, EVAL_NORMAL); + result = op->evaluate (nullptr, exp, EVAL_NORMAL); } catch (const gdb_exception &ex) { @@ -250,91 +220,6 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, } } -/* 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 @@ -635,6 +520,24 @@ fake_method::~fake_method () xfree (m_type.fields ()); } +namespace expr +{ + +value * +type_instance_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + type_instance_flags flags = std::get<0> (m_storage); + std::vector &types = std::get<1> (m_storage); + + fake_method fake_expect_type (flags, types.size (), types.data ()); + return std::get<2> (m_storage)->evaluate (fake_expect_type.type (), + exp, noside); +} + +} + /* Helper for evaluating an OP_VAR_VALUE. */ value * @@ -667,6 +570,23 @@ evaluate_var_value (enum noside noside, const block *blk, symbol *var) return ret; } +namespace expr + +{ + +value * +var_value_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + symbol *var = std::get<0> (m_storage).symbol; + if (SYMBOL_TYPE (var)->code () == TYPE_CODE_ERROR) + error_unknown_type (var->print_name ()); + return evaluate_var_value (noside, std::get<0> (m_storage).block, var); +} + +} /* namespace expr */ + /* Helper for evaluating an OP_VAR_MSYM_VALUE. */ value * @@ -682,14 +602,6 @@ evaluate_var_msym_value (enum noside noside, return value_at_lazy (the_type, address); } -/* Helper for returning a value when handling EVAL_SKIP. */ - -value * -eval_skip_value (expression *exp) -{ - return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1); -} - /* See expression.h. */ value * @@ -763,412 +675,301 @@ 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) +namespace expr { - 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; +value * +operation::evaluate_funcall (struct type *expect_type, + struct expression *exp, + enum noside noside, + const char *function_name, + const std::vector &args) +{ + std::vector vals (args.size ()); - 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) + value *callee = evaluate_with_coercion (exp, noside); + struct type *type = value_type (callee); + if (type->code () == TYPE_CODE_PTR) + type = TYPE_TARGET_TYPE (type); + for (int i = 0; i < args.size (); ++i) { - /* First, evaluate the structure into arg2. */ - pc2 = (*pos)++; - - if (op == STRUCTOP_MEMBER) - { - arg2 = evaluate_subexp_for_address (exp, pos, noside); - } + if (i < type->num_fields ()) + vals[i] = args[i]->evaluate (type->field (i).type (), exp, noside); else - { - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - } + vals[i] = args[i]->evaluate_with_coercion (exp, 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. */ + return evaluate_subexp_do_call (exp, noside, callee, vals, + function_name, expect_type); +} - arg1 = evaluate_subexp (nullptr, exp, pos, noside); +value * +var_value_operation::evaluate_funcall (struct type *expect_type, + struct expression *exp, + enum noside noside, + const std::vector &args) +{ + if (!overload_resolution + || exp->language_defn->la_language != language_cplus) + return operation::evaluate_funcall (expect_type, exp, noside, args); - 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); + std::vector argvec (args.size ()); + for (int i = 0; i < args.size (); ++i) + argvec[i] = args[i]->evaluate_with_coercion (exp, noside); - /* 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)); + struct symbol *symp; + find_overload_match (argvec, NULL, NON_METHOD, + NULL, std::get<0> (m_storage).symbol, + NULL, &symp, NULL, 0, noside); - /* Now, convert these values to an address. */ - arg2 = value_cast (type_ptr, arg2); + if (SYMBOL_TYPE (symp)->code () == TYPE_CODE_ERROR) + error_unknown_type (symp->print_name ()); + value *callee = evaluate_var_value (noside, std::get<0> (m_storage).block, + symp); - long mem_offset = value_as_long (arg1); + return evaluate_subexp_do_call (exp, noside, callee, argvec, + nullptr, expect_type); +} - 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")); +value * +scope_operation::evaluate_funcall (struct type *expect_type, + struct expression *exp, + enum noside noside, + const std::vector &args) +{ + if (!overload_resolution + || exp->language_defn->la_language != language_cplus) + return operation::evaluate_funcall (expect_type, exp, noside, args); + + /* Unpack it locally so we can properly handle overload + resolution. */ + const std::string &name = std::get<1> (m_storage); + struct type *type = std::get<0> (m_storage); + + symbol *function = NULL; + const char *function_name = NULL; + std::vector argvec (1 + args.size ()); + if (type->code () == TYPE_CODE_NAMESPACE) + { + function = cp_lookup_symbol_namespace (type->name (), + name.c_str (), + get_selected_block (0), + VAR_DOMAIN).symbol; + if (function == NULL) + error (_("No symbol \"%s\" in namespace \"%s\"."), + name.c_str (), type->name ()); } - else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) + else { - /* 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); + gdb_assert (type->code () == TYPE_CODE_STRUCT + || type->code () == TYPE_CODE_UNION); + function_name = name.c_str (); - 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); + /* We need a properly typed value for method lookup. */ + argvec[0] = value_zero (type, lval_memory); + } - /* 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); - } + for (int i = 0; i < args.size (); ++i) + argvec[i + 1] = args[i]->evaluate_with_coercion (exp, noside); + gdb::array_view arg_view = argvec; - catch (const gdb_exception_error &except) - { - if (except.error == NOT_FOUND_ERROR) - break; - else - throw; - } + value *callee = nullptr; + if (function_name != nullptr) + { + int static_memfuncp; - 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) + find_overload_match (arg_view, function_name, METHOD, + &argvec[0], nullptr, &callee, nullptr, + &static_memfuncp, 0, noside); + if (!static_memfuncp) { - 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; + /* For the time being, we don't handle this. */ + error (_("Call to overloaded function %s requires " + "`this' pointer"), + function_name); } + + arg_view = arg_view.slice (1); } - else if (op == OP_ADL_FUNC) + else { - /* Save the function position and move pos so that the arguments - can be evaluated. */ - int func_name_len; + symbol *symp; + arg_view = arg_view.slice (1); + find_overload_match (arg_view, nullptr, + NON_METHOD, nullptr, function, + nullptr, &symp, nullptr, 1, noside); + callee = value_of_variable (symp, get_selected_block (0)); + } - save_pos1 = *pos; - tem = 1; + return evaluate_subexp_do_call (exp, noside, callee, arg_view, + nullptr, expect_type); +} - func_name_len = longest_to_int (exp->elts[save_pos1 + 3].longconst); - (*pos) += 6 + BYTES_TO_EXP_ELEM (func_name_len + 1); - } +value * +structop_member_base::evaluate_funcall (struct type *expect_type, + struct expression *exp, + enum noside noside, + const std::vector &args) +{ + /* First, evaluate the structure into lhs. */ + value *lhs; + if (opcode () == STRUCTOP_MEMBER) + lhs = std::get<0> (m_storage)->evaluate_for_address (exp, noside); else - { - /* Non-method function call. */ - save_pos1 = *pos; - tem = 1; + lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); - /* 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; - } + std::vector vals (args.size () + 1); + gdb::array_view val_view = vals; + /* 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. */ + value *rhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); + value *callee; + + type *a1_type = check_typedef (value_type (rhs)); + if (a1_type->code () == TYPE_CODE_METHODPTR) + { + if (noside == EVAL_AVOID_SIDE_EFFECTS) + callee = value_zero (TYPE_TARGET_TYPE (a1_type), not_lval); 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 (); - } + callee = cplus_method_ptr_to_value (&lhs, rhs); - 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); - } - } - } + vals[0] = lhs; } - - /* Evaluate arguments (if not already done, e.g., namespace::func() - and overload-resolution is off). */ - for (; tem <= nargs; tem++) + else if (a1_type->code () == TYPE_CODE_MEMBERPTR) { - /* 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; + 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)); - if (noside == EVAL_SKIP) - return eval_skip_value (exp); + /* Now, convert this value to an address. */ + lhs = value_cast (type_ptr, lhs); - 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); + long mem_offset = value_as_long (rhs); - 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); + callee = value_from_pointer (target_type_ptr, + value_as_long (lhs) + mem_offset); + callee = value_ind (callee); - /* Now fix the expression being evaluated. */ - exp->elts[save_pos1 + 2].symbol = symp; - argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside); + val_view = val_view.slice (1); } + else + error (_("Non-pointer-to-member value used in pointer-to-member " + "construct")); - if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR - || (op == OP_SCOPE && function_name != NULL)) - { - int static_memfuncp; - char *tstr; + for (int i = 0; i < args.size (); ++i) + vals[i + 1] = args[i]->evaluate_with_coercion (exp, noside); - /* Method invocation: stuff "this" as first parameter. If the - method turns out to be static we undo this below. */ - argvec[1] = arg2; + return evaluate_subexp_do_call (exp, noside, callee, val_view, + nullptr, expect_type); - 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)) +value * +structop_base_operation::evaluate_funcall + (struct type *expect_type, struct expression *exp, enum noside noside, + const std::vector &args) +{ + /* Allocate space for the function call arguments, Including space for a + `this' pointer at the start. */ + std::vector vals (args.size () + 1); + /* First, evaluate the structure into vals[0]. */ + enum exp_opcode op = opcode (); + 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. */ + vals[0] = std::get<0> (m_storage)->evaluate_for_address (exp, noside); + } + else + { + vals[0] = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); + /* Check to see if the operator '->' has been overloaded. + If the operator has been overloaded replace vals[0] with the + value returned by the custom operator and continue + evaluation. */ + while (unop_user_defined_p (op, vals[0])) { - /* 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) + struct value *value = nullptr; + try { - /* For the time being, we don't handle this. */ - error (_("Call to overloaded function %s requires " - "`this' pointer"), - function_name); + value = value_x_unop (vals[0], op, noside); + } + catch (const gdb_exception_error &except) + { + if (except.error == NOT_FOUND_ERROR) + break; + else + throw; } - 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++; + vals[0] = value; } } - 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; + /* Evaluate the arguments. The '+ 1' here is to allow for the `this' + pointer we placed into vals[0]. */ + for (int i = 0; i < args.size (); ++i) + vals[i + 1] = args[i]->evaluate_with_coercion (exp, noside); - if (op == OP_VAR_VALUE) - function = exp->elts[save_pos1+2].symbol; + /* The array view includes the `this' pointer. */ + gdb::array_view arg_view (vals); - (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. */ - } + int static_memfuncp; + value *callee; + const char *tstr = std::get<1> (m_storage).c_str (); + if (overload_resolution + && exp->language_defn->la_language == language_cplus) + { + /* Language is C++, do some overload resolution before + evaluation. */ + value *val0 = vals[0]; + find_overload_match (arg_view, tstr, METHOD, + &val0, nullptr, &callee, nullptr, + &static_memfuncp, 0, noside); + vals[0] = val0; } else + /* Non-C++ case -- or no overload resolution. */ { - /* It is probably a C-style function. */ - /* Nothing to be done; argvec already correctly set up. */ + struct value *temp = vals[0]; + + callee = value_struct_elt (&temp, arg_view, 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 it to reflect any + ``this'' changes. */ + vals[0] = value_from_longest (lookup_pointer_type (value_type (temp)), + value_address (temp) + + value_embedded_offset (temp)); } - return evaluate_subexp_do_call (exp, noside, argvec[0], - gdb::make_array_view (argvec + 1, nargs), - var_func_name, expect_type); + /* Take out `this' if needed. */ + if (static_memfuncp) + arg_view = arg_view.slice (1); + + return evaluate_subexp_do_call (exp, noside, callee, arg_view, + nullptr, expect_type); } + +} /* namespace expr */ + /* Return true if type is integral or reference to integral */ static bool @@ -1190,8 +991,6 @@ eval_op_scope (struct type *expect_type, struct expression *exp, enum noside noside, struct type *type, const char *string) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); struct value *arg1 = value_aggregate_elt (type, string, expect_type, 0, noside); if (arg1 == NULL) @@ -1205,8 +1004,6 @@ struct value * eval_op_var_entry_value (struct type *expect_type, struct expression *exp, enum noside noside, symbol *sym) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (SYMBOL_TYPE (sym), not_lval); @@ -1224,14 +1021,15 @@ eval_op_var_entry_value (struct type *expect_type, struct expression *exp, struct value * eval_op_var_msym_value (struct type *expect_type, struct expression *exp, enum noside noside, bool outermost_p, - minimal_symbol *msymbol, struct objfile *objfile) + bound_minimal_symbol msymbol) { - value *val = evaluate_var_msym_value (noside, objfile, msymbol); + value *val = evaluate_var_msym_value (noside, msymbol.objfile, + msymbol.minsym); struct type *type = value_type (val); if (type->code () == TYPE_CODE_ERROR && (noside != EVAL_AVOID_SIDE_EFFECTS || !outermost_p)) - error_unknown_type (msymbol->print_name ()); + error_unknown_type (msymbol.minsym->print_name ()); return val; } @@ -1242,8 +1040,6 @@ eval_op_func_static_var (struct type *expect_type, struct expression *exp, enum noside noside, value *func, const char *var) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); CORE_ADDR addr = value_address (func); const block *blk = block_for_pc (addr); struct block_symbol sym = lookup_symbol (var, blk, VAR_DOMAIN, NULL); @@ -1284,12 +1080,10 @@ eval_op_register (struct type *expect_type, struct expression *exp, /* Helper function that implements the body of OP_STRING. */ -static struct value * +struct value * eval_op_string (struct type *expect_type, struct expression *exp, enum noside noside, int len, const char *string) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); struct type *type = language_string_char_type (exp->language_defn, exp->gdbarch); return value_string (string, len, type); @@ -1297,14 +1091,11 @@ eval_op_string (struct type *expect_type, struct expression *exp, /* Helper function that implements the body of OP_OBJC_SELECTOR. */ -static struct value * +struct value * eval_op_objc_selector (struct type *expect_type, struct expression *exp, enum noside noside, const char *sel) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - struct type *selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr; return value_from_longest (selector_type, lookup_child_selector (exp->gdbarch, sel)); @@ -1312,28 +1103,23 @@ eval_op_objc_selector (struct type *expect_type, struct expression *exp, /* Helper function that implements the body of BINOP_CONCAT. */ -static struct value * +struct value * eval_op_concat (struct type *expect_type, struct expression *exp, - enum noside noside, - enum exp_opcode op, struct value *arg1, struct value *arg2) + enum noside noside, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - if (binop_user_defined_p (op, arg1, arg2)) - return value_x_binop (arg1, arg2, op, OP_NULL, noside); + if (binop_user_defined_p (BINOP_CONCAT, arg1, arg2)) + return value_x_binop (arg1, arg2, BINOP_CONCAT, OP_NULL, noside); else return value_concat (arg1, arg2); } /* A helper function for TERNOP_SLICE. */ -static struct value * +struct value * eval_op_ternop (struct type *expect_type, struct expression *exp, enum noside noside, struct value *array, struct value *low, struct value *upper) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); int lowbound = value_as_long (low); int upperbound = value_as_long (upper); return value_slice (array, lowbound, upperbound - lowbound + 1); @@ -1341,14 +1127,12 @@ eval_op_ternop (struct type *expect_type, struct expression *exp, /* A helper function for STRUCTOP_STRUCT. */ -static struct value * +struct value * eval_op_structop_struct (struct type *expect_type, struct expression *exp, enum noside noside, struct value *arg1, const char *string) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - struct value *arg3 = value_struct_elt (&arg1, NULL, string, + struct value *arg3 = value_struct_elt (&arg1, {}, string, NULL, "structure"); if (noside == EVAL_AVOID_SIDE_EFFECTS) arg3 = value_zero (value_type (arg3), VALUE_LVAL (arg3)); @@ -1357,22 +1141,19 @@ eval_op_structop_struct (struct type *expect_type, struct expression *exp, /* A helper function for STRUCTOP_PTR. */ -static struct value * +struct value * eval_op_structop_ptr (struct type *expect_type, struct expression *exp, - enum noside noside, enum exp_opcode op, + enum noside noside, struct value *arg1, const char *string) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - /* Check to see if operator '->' has been overloaded. If so replace arg1 with the value returned by evaluating operator->(). */ - while (unop_user_defined_p (op, arg1)) + while (unop_user_defined_p (STRUCTOP_PTR, arg1)) { struct value *value = NULL; try { - value = value_x_unop (arg1, op, noside); + value = value_x_unop (arg1, STRUCTOP_PTR, noside); } catch (const gdb_exception_error &except) @@ -1407,7 +1188,7 @@ eval_op_structop_ptr (struct type *expect_type, struct expression *exp, } } - struct value *arg3 = value_struct_elt (&arg1, NULL, string, + struct value *arg3 = value_struct_elt (&arg1, {}, string, NULL, "structure pointer"); if (noside == EVAL_AVOID_SIDE_EFFECTS) arg3 = value_zero (value_type (arg3), VALUE_LVAL (arg3)); @@ -1416,16 +1197,13 @@ eval_op_structop_ptr (struct type *expect_type, struct expression *exp, /* A helper function for STRUCTOP_MEMBER. */ -static struct value * +struct value * eval_op_member (struct type *expect_type, struct expression *exp, enum noside noside, struct value *arg1, struct value *arg2) { long mem_offset; - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - struct value *arg3; struct type *type = check_typedef (value_type (arg2)); switch (type->code ()) @@ -1459,15 +1237,13 @@ eval_op_member (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_ADD. */ -static struct value * +struct value * eval_op_add (struct type *expect_type, struct expression *exp, - enum noside noside, enum exp_opcode op, + enum noside noside, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - if (binop_user_defined_p (op, arg1, arg2)) - return value_x_binop (arg1, arg2, op, OP_NULL, noside); + if (binop_user_defined_p (BINOP_ADD, arg1, arg2)) + return value_x_binop (arg1, arg2, BINOP_ADD, OP_NULL, noside); else if (ptrmath_type_p (exp->language_defn, value_type (arg1)) && is_integral_or_integral_reference (value_type (arg2))) return value_ptradd (arg1, value_as_long (arg2)); @@ -1483,15 +1259,13 @@ eval_op_add (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_SUB. */ -static struct value * +struct value * eval_op_sub (struct type *expect_type, struct expression *exp, - enum noside noside, enum exp_opcode op, + enum noside noside, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - if (binop_user_defined_p (op, arg1, arg2)) - return value_x_binop (arg1, arg2, op, OP_NULL, noside); + if (binop_user_defined_p (BINOP_SUB, arg1, arg2)) + return value_x_binop (arg1, arg2, BINOP_SUB, OP_NULL, noside); else if (ptrmath_type_p (exp->language_defn, value_type (arg1)) && ptrmath_type_p (exp->language_defn, value_type (arg2))) { @@ -1511,13 +1285,11 @@ eval_op_sub (struct type *expect_type, struct expression *exp, /* Helper function for several different binary operations. */ -static struct value * +struct value * eval_op_binary (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (binop_user_defined_p (op, arg1, arg2)) return value_x_binop (arg1, arg2, op, OP_NULL, noside); else @@ -1558,13 +1330,11 @@ eval_op_binary (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_SUBSCRIPT. */ -static struct value * +struct value * eval_op_subscript (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (binop_user_defined_p (op, arg1, arg2)) return value_x_binop (arg1, arg2, op, OP_NULL, noside); else @@ -1594,13 +1364,11 @@ eval_op_subscript (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_EQUAL. */ -static struct value * +struct value * eval_op_equal (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (binop_user_defined_p (op, arg1, arg2)) { return value_x_binop (arg1, arg2, op, OP_NULL, noside); @@ -1617,13 +1385,11 @@ eval_op_equal (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_NOTEQUAL. */ -static struct value * +struct value * eval_op_notequal (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (binop_user_defined_p (op, arg1, arg2)) { return value_x_binop (arg1, arg2, op, OP_NULL, noside); @@ -1640,13 +1406,11 @@ eval_op_notequal (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_LESS. */ -static struct value * +struct value * eval_op_less (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (binop_user_defined_p (op, arg1, arg2)) { return value_x_binop (arg1, arg2, op, OP_NULL, noside); @@ -1663,13 +1427,11 @@ eval_op_less (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_GTR. */ -static struct value * +struct value * eval_op_gtr (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (binop_user_defined_p (op, arg1, arg2)) { return value_x_binop (arg1, arg2, op, OP_NULL, noside); @@ -1686,13 +1448,11 @@ eval_op_gtr (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_GEQ. */ -static struct value * +struct value * eval_op_geq (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (binop_user_defined_p (op, arg1, arg2)) { return value_x_binop (arg1, arg2, op, OP_NULL, noside); @@ -1709,13 +1469,11 @@ eval_op_geq (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_LEQ. */ -static struct value * +struct value * eval_op_leq (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (binop_user_defined_p (op, arg1, arg2)) { return value_x_binop (arg1, arg2, op, OP_NULL, noside); @@ -1732,13 +1490,11 @@ eval_op_leq (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_REPEAT. */ -static struct value * +struct value * eval_op_repeat (struct type *expect_type, struct expression *exp, - enum noside noside, + enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); struct type *type = check_typedef (value_type (arg2)); if (type->code () != TYPE_CODE_INT && type->code () != TYPE_CODE_ENUM) @@ -1754,13 +1510,11 @@ eval_op_repeat (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_PLUS. */ -static struct value * +struct value * eval_op_plus (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (unop_user_defined_p (op, arg1)) return value_x_unop (arg1, op, noside); else @@ -1772,13 +1526,11 @@ eval_op_plus (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_NEG. */ -static struct value * +struct value * eval_op_neg (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (unop_user_defined_p (op, arg1)) return value_x_unop (arg1, op, noside); else @@ -1790,13 +1542,11 @@ eval_op_neg (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_COMPLEMENT. */ -static struct value * +struct value * eval_op_complement (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (unop_user_defined_p (UNOP_COMPLEMENT, arg1)) return value_x_unop (arg1, UNOP_COMPLEMENT, noside); else @@ -1808,13 +1558,11 @@ eval_op_complement (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_LOGICAL_NOT. */ -static struct value * +struct value * eval_op_lognot (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (unop_user_defined_p (op, arg1)) return value_x_unop (arg1, op, noside); else @@ -1827,9 +1575,9 @@ eval_op_lognot (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_IND. */ -static struct value * +struct value * eval_op_ind (struct type *expect_type, struct expression *exp, - enum noside noside, enum exp_opcode op, + enum noside noside, struct value *arg1) { struct type *type = check_typedef (value_type (arg1)); @@ -1837,10 +1585,8 @@ eval_op_ind (struct type *expect_type, struct expression *exp, || type->code () == TYPE_CODE_MEMBERPTR) error (_("Attempt to dereference pointer " "to member without an object")); - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - if (unop_user_defined_p (op, arg1)) - return value_x_unop (arg1, op, noside); + if (unop_user_defined_p (UNOP_IND, arg1)) + return value_x_unop (arg1, UNOP_IND, noside); else if (noside == EVAL_AVOID_SIDE_EFFECTS) { type = check_typedef (value_type (arg1)); @@ -1850,12 +1596,10 @@ eval_op_ind (struct type *expect_type, struct expression *exp, There is a risk that this dereference will have side-effects in the inferior, but being able to print accurate type information seems worth the risk. */ - if ((type->code () != TYPE_CODE_PTR - && !TYPE_IS_REFERENCE (type)) + if (!type->is_pointer_or_reference () || !is_dynamic_type (TYPE_TARGET_TYPE (type))) { - if (type->code () == TYPE_CODE_PTR - || TYPE_IS_REFERENCE (type) + if (type->is_pointer_or_reference () /* In C you can dereference an array to get the 1st elt. */ || type->code () == TYPE_CODE_ARRAY) return value_zero (TYPE_TARGET_TYPE (type), @@ -1881,7 +1625,7 @@ eval_op_ind (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_ALIGNOF. */ -static struct value * +struct value * eval_op_alignof (struct type *expect_type, struct expression *exp, enum noside noside, struct value *arg1) @@ -1897,13 +1641,11 @@ eval_op_alignof (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_MEMVAL. */ -static struct value * +struct value * eval_op_memval (struct type *expect_type, struct expression *exp, enum noside noside, struct value *arg1, struct type *type) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (type, lval_memory); else @@ -1912,12 +1654,12 @@ eval_op_memval (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_PREINCREMENT. */ -static struct value * +struct value * eval_op_preinc (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1) { - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) + if (noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; else if (unop_user_defined_p (op, arg1)) { @@ -1943,12 +1685,12 @@ eval_op_preinc (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_PREDECREMENT. */ -static struct value * +struct value * eval_op_predec (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1) { - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) + if (noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; else if (unop_user_defined_p (op, arg1)) { @@ -1974,12 +1716,12 @@ eval_op_predec (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_POSTINCREMENT. */ -static struct value * +struct value * eval_op_postinc (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1) { - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) + if (noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; else if (unop_user_defined_p (op, arg1)) { @@ -2008,12 +1750,12 @@ eval_op_postinc (struct type *expect_type, struct expression *exp, /* A helper function for UNOP_POSTDECREMENT. */ -static struct value * +struct value * eval_op_postdec (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1) { - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) + if (noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; else if (unop_user_defined_p (op, arg1)) { @@ -2042,13 +1784,11 @@ eval_op_postdec (struct type *expect_type, struct expression *exp, /* A helper function for OP_TYPE. */ -static struct value * +struct value * eval_op_type (struct type *expect_type, struct expression *exp, enum noside noside, struct type *type) { - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - else if (noside == EVAL_AVOID_SIDE_EFFECTS) + if (noside == EVAL_AVOID_SIDE_EFFECTS) return allocate_value (type); else error (_("Attempt to use a type name as an expression")); @@ -2056,12 +1796,12 @@ eval_op_type (struct type *expect_type, struct expression *exp, /* A helper function for BINOP_ASSIGN_MODIFY. */ -static struct value * +struct value * eval_binop_assign_modify (struct type *expect_type, struct expression *exp, enum noside noside, enum exp_opcode op, struct value *arg1, struct value *arg2) { - if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) + if (noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; if (binop_user_defined_p (op, arg1, arg2)) return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op, noside); @@ -2230,8 +1970,8 @@ eval_op_objc_msgcall (struct type *expect_type, struct expression *exp, /* The address might point to a function descriptor; resolve it to the actual code address instead. */ - addr = gdbarch_convert_from_func_ptr_addr (exp->gdbarch, addr, - current_top_target ()); + addr = gdbarch_convert_from_func_ptr_addr + (exp->gdbarch, addr, current_inferior ()->top_target ()); /* Is it a high_level symbol? */ sym = find_pc_function (addr); @@ -2311,8 +2051,6 @@ eval_op_objc_msgcall (struct type *expect_type, struct expression *exp, called_method = msg_send; } - if (noside == EVAL_SKIP) - return eval_skip_value (exp); if (noside == EVAL_AVOID_SIDE_EFFECTS) { @@ -2368,8 +2106,6 @@ eval_multi_subscript (struct type *expect_type, struct expression *exp, enum noside noside, value *arg1, gdb::array_view args) { - if (noside == EVAL_SKIP) - return arg1; for (value *arg2 : args) { if (binop_user_defined_p (MULTI_SUBSCRIPT, arg1, arg2)) @@ -2401,738 +2137,338 @@ eval_multi_subscript (struct type *expect_type, struct expression *exp, return (arg1); } -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); - } +namespace expr +{ - 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 * +objc_msgcall_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + enum noside sub_no_side = EVAL_NORMAL; + struct type *selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr; - { - value *func = evaluate_subexp_standard (NULL, exp, pos, noside); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + sub_no_side = EVAL_NORMAL; + else + sub_no_side = noside; + value *target + = std::get<1> (m_storage)->evaluate (selector_type, exp, sub_no_side); - return eval_op_func_static_var (expect_type, exp, noside, func, - &exp->elts[pc + 2].string); - } + if (value_as_long (target) == 0) + sub_no_side = EVAL_AVOID_SIDE_EFFECTS; + else + sub_no_side = noside; + std::vector &args = std::get<2> (m_storage); + value **argvec = XALLOCAVEC (struct value *, args.size () + 3); + argvec[0] = nullptr; + argvec[1] = nullptr; + for (int i = 0; i < args.size (); ++i) + argvec[i + 2] = args[i]->evaluate_with_coercion (exp, sub_no_side); + argvec[args.size () + 2] = nullptr; - case OP_LAST: - (*pos) += 2; - return - access_value_history (longest_to_int (exp->elts[pc + 1].longconst)); + return eval_op_objc_msgcall (expect_type, exp, noside, std:: + get<0> (m_storage), target, + gdb::make_array_view (argvec, + args.size () + 3)); +} - case OP_REGISTER: - { - const char *name = &exp->elts[pc + 2].string; +value * +multi_subscript_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + value *arg1 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside); + std::vector &values = std::get<1> (m_storage); + value **argvec = XALLOCAVEC (struct value *, values.size ()); + for (int ix = 0; ix < values.size (); ++ix) + argvec[ix] = values[ix]->evaluate_with_coercion (exp, noside); + return eval_multi_subscript (expect_type, exp, noside, arg1, + gdb::make_array_view (argvec, values.size ())); +} - (*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); +value * +logical_and_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); - memset (value_contents_raw (rec), '\0', TYPE_LENGTH (type)); - return evaluate_struct_tuple (rec, exp, pos, noside, nargs); - } + value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, + EVAL_AVOID_SIDE_EFFECTS); - if (expect_type != nullptr && noside != EVAL_SKIP - && type->code () == TYPE_CODE_ARRAY) + if (binop_user_defined_p (BINOP_LOGICAL_AND, arg1, arg2)) + { + arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); + return value_x_binop (arg1, arg2, BINOP_LOGICAL_AND, OP_NULL, noside); + } + else + { + bool tem = value_logical_not (arg1); + if (!tem) { - 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; + arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); + tem = value_logical_not (arg2); } + struct type *type = language_bool_type (exp->language_defn, + exp->gdbarch); + return value_from_longest (type, !tem); + } +} - 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); +value * +logical_or_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); - 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); - } + value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, + EVAL_AVOID_SIDE_EFFECTS); - 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 + if (binop_user_defined_p (BINOP_LOGICAL_OR, arg1, arg2)) + { + arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); + return value_x_binop (arg1, arg2, BINOP_LOGICAL_OR, OP_NULL, noside); + } + else + { + bool tem = value_logical_not (arg1); + if (tem) { - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - evaluate_subexp (nullptr, exp, pos, EVAL_SKIP); - return arg2; + arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); + tem = value_logical_not (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 type *type = language_bool_type (exp->language_defn, + exp->gdbarch); + return value_from_longest (type, !tem); + } +} - struct value *target = NULL; +value * +adl_func_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + std::vector &arg_ops = std::get<2> (m_storage); + std::vector args (arg_ops.size ()); + for (int i = 0; i < arg_ops.size (); ++i) + args[i] = arg_ops[i]->evaluate_with_coercion (exp, noside); - struct type *selector_type = NULL; + struct symbol *symp; + find_overload_match (args, std::get<0> (m_storage).c_str (), + NON_METHOD, + nullptr, nullptr, + nullptr, &symp, nullptr, 0, noside); + if (SYMBOL_TYPE (symp)->code () == TYPE_CODE_ERROR) + error_unknown_type (symp->print_name ()); + value *callee = evaluate_var_value (noside, std::get<1> (m_storage), symp); + return evaluate_subexp_do_call (exp, noside, callee, args, + nullptr, expect_type); - selector = exp->elts[pc + 1].longconst; - nargs = exp->elts[pc + 2].longconst; - argvec = XALLOCAVEC (struct value *, nargs + 3); +} - (*pos) += 3; +/* This function evaluates brace-initializers (in C/C++) for + structure types. */ - selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr; +struct value * +array_operation::evaluate_struct_tuple (struct value *struct_val, + struct expression *exp, + enum noside noside, int nargs) +{ + const std::vector &in_args = std::get<2> (m_storage); + struct type *struct_type = check_typedef (value_type (struct_val)); + struct type *field_type; + int fieldno = -1; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - sub_no_side = EVAL_NORMAL; - else - sub_no_side = noside; + int idx = 0; + while (--nargs >= 0) + { + struct value *val = NULL; + int bitpos, bitsize; + bfd_byte *addr; - target = evaluate_subexp (selector_type, exp, pos, sub_no_side); + 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 + && struct_type->field (fieldno).name ()[0] == '0') + error (_("don't know which variant you want to set")); - if (value_as_long (target) == 0) - sub_no_side = EVAL_SKIP; - else - sub_no_side = noside; + /* 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. */ - /* Now depending on whether we found a symbol for the method, - we will either call the runtime dispatcher or the method - directly. */ + field_type = struct_type->field (fieldno).type (); + if (val == 0) + val = in_args[idx++]->evaluate (field_type, exp, noside); - 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; + /* Now actually set the field in struct_val. */ - auto call_args = gdb::make_array_view (argvec, nargs + 3); + /* Assign val to field fieldno. */ + if (value_type (val) != field_type) + val = value_cast (field_type, val); - 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, op, arg1, - &exp->elts[pc + 2].string); - - case STRUCTOP_MEMBER: - case STRUCTOP_MPTR: - if (op == STRUCTOP_MEMBER) - arg1 = evaluate_subexp_for_address (exp, pos, noside); + bitsize = TYPE_FIELD_BITSIZE (struct_type, fieldno); + bitpos = struct_type->field (fieldno).loc_bitpos (); + addr = value_contents_writeable (struct_val).data () + bitpos / 8; + if (bitsize) + modify_field (struct_type, addr, + value_as_long (val), bitpos % 8, bitsize); else - arg1 = evaluate_subexp (nullptr, exp, pos, noside); + memcpy (addr, value_contents (val).data (), + TYPE_LENGTH (value_type (val))); - arg2 = evaluate_subexp (nullptr, exp, pos, noside); + } + return struct_val; +} - return eval_op_member (expect_type, exp, noside, arg1, arg2); +value * +array_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + int tem; + int tem2 = std::get<0> (m_storage); + int tem3 = std::get<1> (m_storage); + const std::vector &in_args = std::get<2> (m_storage); + int nargs = tem3 - tem2 + 1; + struct type *type = expect_type ? check_typedef (expect_type) : nullptr; - 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); - } + if (expect_type != nullptr + && type->code () == TYPE_CODE_STRUCT) + { + struct value *rec = allocate_value (expect_type); - 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, op, 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, op, 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, op, 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); - } + memset (value_contents_raw (rec).data (), '\0', TYPE_LENGTH (type)); + return evaluate_struct_tuple (rec, exp, noside, nargs); + } - oldpos = *pos; - arg2 = evaluate_subexp (nullptr, exp, pos, EVAL_AVOID_SIDE_EFFECTS); - *pos = oldpos; + if (expect_type != nullptr + && 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 (binop_user_defined_p (op, arg1, arg2)) + if (!get_discrete_bounds (range_type, &low_bound, &high_bound)) { - arg2 = evaluate_subexp (nullptr, exp, pos, noside); - return value_x_binop (arg1, arg2, op, OP_NULL, noside); + low_bound = 0; + high_bound = (TYPE_LENGTH (type) / element_size) - 1; } - else + index = low_bound; + memset (value_contents_raw (array).data (), 0, TYPE_LENGTH (expect_type)); + for (tem = nargs; --nargs >= 0;) { - 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))); - } + struct value *element; - 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); + element = in_args[index - low_bound]->evaluate (element_type, + exp, 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).data () + + (index - low_bound) * element_size, + value_contents (element).data (), + element_size); + index++; } + return array; + } - 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))); - } + if (expect_type != nullptr + && type->code () == TYPE_CODE_SET) + { + struct value *set = allocate_value (expect_type); + gdb_byte *valaddr = value_contents_raw (set).data (); + struct type *element_type = type->index_type (); + struct type *check_type = element_type; + LONGEST low_bound, high_bound; - 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, 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, op, 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); + /* Get targettype of elementtype. */ + while (check_type->code () == TYPE_CODE_RANGE + || check_type->code () == TYPE_CODE_TYPEDEF) + check_type = TYPE_TARGET_TYPE (check_type); - 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) + if (!get_discrete_bounds (element_type, &low_bound, &high_bound)) + error (_("(power)set type with unknown size")); + memset (valaddr, '\0', TYPE_LENGTH (type)); + int idx = 0; + for (tem = 0; tem < nargs; tem++) { - 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)) + LONGEST range_low, range_high; + struct type *range_low_type, *range_high_type; + struct value *elem_val; + + elem_val = in_args[idx++]->evaluate (element_type, exp, 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) { - type = value_type (result); - - if (!TYPE_IS_REFERENCE (type)) - { - type = lookup_lvalue_reference_type (type); - result = allocate_value (type); - } + 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; - return result; + 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; + } } - 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. */ + return set; + } - error (_("GDB does not (yet) know how to " - "evaluate that kind of expression")); + value **argvec = XALLOCAVEC (struct value *, nargs); + for (tem = 0; tem < nargs; tem++) + { + /* Ensure that array expressions are coerced into pointer + objects. */ + argvec[tem] = in_args[tem]->evaluate_with_coercion (exp, noside); } + return value_array (tem2, tem3, argvec); +} - gdb_assert_not_reached ("missed return?"); } + /* Helper for evaluate_subexp_for_address. */ @@ -3157,117 +2493,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 { @@ -3277,8 +2502,6 @@ operation::evaluate_for_cast (struct type *expect_type, enum noside noside) { value *val = evaluate (expect_type, exp, noside); - if (noside == EVAL_SKIP) - return eval_skip_value (exp); return value_cast (expect_type, val); } @@ -3301,13 +2524,28 @@ scope_operation::evaluate_for_address (struct expression *exp, return x; } +value * +unop_ind_base_operation::evaluate_for_address (struct expression *exp, + enum noside noside) +{ + value *x = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); + + /* We can't optimize out "&*" if there's a user-defined operator*. */ + if (unop_user_defined_p (UNOP_IND, x)) + { + x = value_x_unop (x, UNOP_IND, noside); + return evaluate_subexp_for_address_base (exp, noside, x); + } + + return coerce_array (x); +} + value * var_msym_value_operation::evaluate_for_address (struct expression *exp, enum noside noside) { - value *val = evaluate_var_msym_value (noside, - std::get<1> (m_storage), - std::get<0> (m_storage)); + const bound_minimal_symbol &b = std::get<0> (m_storage); + value *val = evaluate_var_msym_value (noside, b.objfile, b.minsym); if (noside == EVAL_AVOID_SIDE_EFFECTS) { struct type *type = lookup_pointer_type (value_type (val)); @@ -3317,51 +2555,69 @@ var_msym_value_operation::evaluate_for_address (struct expression *exp, return value_addr (val); } +value * +unop_memval_operation::evaluate_for_address (struct expression *exp, + enum noside noside) +{ + return value_cast (lookup_pointer_type (std::get<1> (m_storage)), + std::get<0> (m_storage)->evaluate (nullptr, exp, noside)); } -/* 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. */ +value * +unop_memval_type_operation::evaluate_for_address (struct expression *exp, + enum noside noside) +{ + value *typeval = std::get<0> (m_storage)->evaluate (nullptr, exp, + EVAL_AVOID_SIDE_EFFECTS); + struct type *type = value_type (typeval); + return value_cast (lookup_pointer_type (type), + std::get<1> (m_storage)->evaluate (nullptr, exp, noside)); +} -struct value * -evaluate_subexp_with_coercion (struct expression *exp, - int *pos, enum noside noside) +value * +var_value_operation::evaluate_for_address (struct expression *exp, + enum noside noside) { - enum exp_opcode op; - int pc; - struct value *val; - struct symbol *var; - struct type *type; + symbol *var = std::get<0> (m_storage).symbol; - pc = (*pos); - op = exp->elts[pc].opcode; + /* 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))) + return operation::evaluate_for_address (exp, noside); - switch (op) + if (noside == EVAL_AVOID_SIDE_EFFECTS) { - 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 */ + struct type *type = lookup_pointer_type (SYMBOL_TYPE (var)); + enum address_class sym_class = SYMBOL_CLASS (var); - default: - return evaluate_subexp (nullptr, exp, pos, noside); + 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, std::get<0> (m_storage).block); +} + +value * +var_value_operation::evaluate_with_coercion (struct expression *exp, + enum noside noside) +{ + struct symbol *var = std::get<0> (m_storage).symbol; + struct type *type = check_typedef (SYMBOL_TYPE (var)); + if (type->code () == TYPE_CODE_ARRAY + && !type->is_vector () + && CAST_IS_CONVERSION (exp->language_defn)) + { + struct value *val = address_of_variable (var, + std::get<0> (m_storage).block); + return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), val); } + return evaluate (nullptr, exp, noside); +} + } /* Helper function for evaluating the size of a type. */ @@ -3381,132 +2637,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 { @@ -3522,79 +2652,107 @@ var_msym_value_operation::evaluate_for_sizeof (struct expression *exp, enum noside noside) { - minimal_symbol *msymbol = std::get<0> (m_storage); - value *mval = evaluate_var_msym_value (noside, - std::get<1> (m_storage), - msymbol); + const bound_minimal_symbol &b = std::get<0> (m_storage); + value *mval = evaluate_var_msym_value (noside, b.objfile, b.minsym); struct type *type = value_type (mval); if (type->code () == TYPE_CODE_ERROR) - error_unknown_type (msymbol->print_name ()); + error_unknown_type (b.minsym->print_name ()); /* FIXME: This should be size_t. */ struct type *size_type = builtin_type (exp->gdbarch)->builtin_int; return value_from_longest (size_type, TYPE_LENGTH (type)); } -} - -/* 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) +value * +subscript_operation::evaluate_for_sizeof (struct expression *exp, + enum noside noside) { - 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) + if (noside == EVAL_NORMAL) { - (*pos) += 4; - - value *val; - if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE) + value *val = std::get<0> (m_storage)->evaluate (nullptr, exp, + EVAL_AVOID_SIDE_EFFECTS); + struct type *type = check_typedef (value_type (val)); + if (type->code () == TYPE_CODE_ARRAY) { - 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); + 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 (nullptr, exp, EVAL_NORMAL); + /* FIXME: This should be size_t. */ + struct type *size_type + = builtin_type (exp->gdbarch)->builtin_int; + return value_from_longest + (size_type, (LONGEST) TYPE_LENGTH (value_type (val))); + } + } } - 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); + return operation::evaluate_for_sizeof (exp, noside); +} - val = value_cast (to_type, val); +value * +unop_ind_base_operation::evaluate_for_sizeof (struct expression *exp, + enum noside noside) +{ + value *val = std::get<0> (m_storage)->evaluate (nullptr, exp, + EVAL_AVOID_SIDE_EFFECTS); + struct type *type = check_typedef (value_type (val)); + if (!type->is_pointer_or_reference () + && 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)); + /* FIXME: This should be size_t. */ + struct type *size_type = builtin_type (exp->gdbarch)->builtin_int; + return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type)); +} - /* 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 * +unop_memval_operation::evaluate_for_sizeof (struct expression *exp, + enum noside noside) +{ + return evaluate_subexp_for_sizeof_base (exp, std::get<1> (m_storage)); +} - value *val = evaluate_subexp (to_type, exp, pos, noside); - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - return value_cast (to_type, val); +value * +unop_memval_type_operation::evaluate_for_sizeof (struct expression *exp, + enum noside noside) +{ + value *typeval = std::get<0> (m_storage)->evaluate (nullptr, exp, + EVAL_AVOID_SIDE_EFFECTS); + return evaluate_subexp_for_sizeof_base (exp, value_type (typeval)); } -namespace expr +value * +var_value_operation::evaluate_for_sizeof (struct expression *exp, + enum noside noside) { + struct type *type = SYMBOL_TYPE (std::get<0> (m_storage).symbol); + if (is_dynamic_type (type)) + { + value *val = evaluate (nullptr, exp, EVAL_NORMAL); + type = value_type (val); + if (type->code () == TYPE_CODE_ARRAY) + { + /* FIXME: This should be size_t. */ + struct type *size_type = builtin_type (exp->gdbarch)->builtin_int; + 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); + } + } + return evaluate_subexp_for_sizeof_base (exp, type); +} value * var_msym_value_operation::evaluate_for_cast (struct type *to_type, @@ -3604,12 +2762,29 @@ var_msym_value_operation::evaluate_for_cast (struct type *to_type, if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (to_type, not_lval); - value *val = evaluate_var_msym_value (noside, - std::get<1> (m_storage), - std::get<0> (m_storage)); + const bound_minimal_symbol &b = std::get<0> (m_storage); + value *val = evaluate_var_msym_value (noside, b.objfile, b.minsym); + + 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; +} - if (noside == EVAL_SKIP) - return eval_skip_value (exp); +value * +var_value_operation::evaluate_for_cast (struct type *to_type, + struct expression *exp, + enum noside noside) +{ + value *val = evaluate_var_value (noside, + std::get<0> (m_storage).block, + std::get<0> (m_storage).symbol); val = value_cast (to_type, val); @@ -3638,7 +2813,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->op.get ()); + if (op == nullptr) error (_("Internal error in eval_type.")); - return expr->elts[1].type; + return op->get_type (); }