/* Evaluate expressions for GDB.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "valprint.h"
#include "gdb_obstack.h"
#include "objfiles.h"
+#include "typeprint.h"
#include <ctype.h>
-/* This is defined in valops.c */
-extern int overload_resolution;
-
/* Prototypes for local functions. */
static struct value *evaluate_subexp_for_sizeof (struct expression *, int *,
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);
evaluate_subexp (struct type *expect_type, struct expression *exp,
int *pos, enum noside noside)
{
- struct cleanup *cleanups;
struct value *retval;
- int cleanup_temps = 0;
+ gdb::optional<enable_thread_stack_temporaries> stack_temporaries;
if (*pos == 0 && target_has_execution
&& exp->language_defn->la_language == language_cplus
- && !thread_stack_temporaries_enabled_p (inferior_ptid))
- {
- cleanups = enable_thread_stack_temporaries (inferior_ptid);
- cleanup_temps = 1;
- }
+ && !thread_stack_temporaries_enabled_p (inferior_thread ()))
+ stack_temporaries.emplace (inferior_thread ());
retval = (*exp->language_defn->la_exp_desc->evaluate_exp)
(expect_type, exp, pos, noside);
- if (cleanup_temps)
- {
- if (value_in_thread_stack_temporaries (retval, inferior_ptid))
- retval = value_non_lval (retval);
- do_cleanups (cleanups);
- }
+ if (stack_temporaries.has_value ()
+ && value_in_thread_stack_temporaries (retval, inferior_thread ()))
+ retval = value_non_lval (retval);
return retval;
}
struct value *
parse_to_comma_and_eval (const char **expp)
{
- expression_up expr = parse_exp_1 (expp, 0, (struct block *) 0, 1);
+ expression_up expr = parse_exp_1 (expp, 0, nullptr, 1);
return evaluate_expression (expr.get ());
}
set to any referenced values. *VALP will never be a lazy value.
This is the value which we store in struct breakpoint.
- If VAL_CHAIN is non-NULL, *VAL_CHAIN will be released from the
- value chain. The caller must free the values individually. If
- VAL_CHAIN is NULL, all generated values will be left on the value
- chain. */
+ If VAL_CHAIN is non-NULL, the values put into *VAL_CHAIN will be
+ released from the value chain. If VAL_CHAIN is NULL, all generated
+ values will be left on the value chain. */
void
fetch_subexp_value (struct expression *exp, int *pc, struct value **valp,
- struct value **resultp, struct value **val_chain,
+ struct value **resultp,
+ std::vector<value_ref_ptr> *val_chain,
int preserve_errors)
{
struct value *mark, *new_mark, *result;
if (resultp)
*resultp = NULL;
if (val_chain)
- *val_chain = NULL;
+ val_chain->clear ();
/* Evaluate the expression. */
mark = value_mark ();
result = NULL;
- TRY
+ try
{
result = evaluate_subexp (NULL_TYPE, exp, pc, EVAL_NORMAL);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
/* Ignore memory errors if we want watchpoints pointing at
inaccessible memory to still be created; otherwise, throw the
case MEMORY_ERROR:
if (!preserve_errors)
break;
+ /* Fall through. */
default:
- throw_exception (ex);
+ throw;
break;
}
}
- END_CATCH
new_mark = value_mark ();
if (mark == new_mark)
else
{
- TRY
+ try
{
value_fetch_lazy (result);
*valp = result;
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
}
- END_CATCH
}
}
{
/* Return the chain of intermediate values. We use this to
decide which addresses to watch. */
- *val_chain = new_mark;
- value_release_to_mark (mark);
+ *val_chain = value_release_to_mark (mark);
}
}
subexpression of the left-hand-side of the dereference. This is
used when completing field names. */
-char *
+const char *
extract_field_op (struct expression *exp, int *subexp)
{
int tem;
/* Recursive helper function for setting elements of array tuples.
The target is ARRAY (which has bounds LOW_BOUND to HIGH_BOUND); the
element value is ELEMENT; EXP, POS and NOSIDE are as usual.
- Evaluates index expresions and sets the specified element(s) of
+ Evaluates index expressions and sets the specified element(s) of
ARRAY to ELEMENT. Returns last index value. */
static LONGEST
{
default:
/* Perform integral promotion for ANSI C/C++.
- If not appropropriate for any particular language
+ If not appropriate for any particular language
it needs to modify this function. */
{
struct type *builtin_int = builtin_type (gdbarch)->builtin_int;
break;
case language_opencl:
if (result_len <= TYPE_LENGTH (lookup_signed_typename
- (language, gdbarch, "int")))
+ (language, "int")))
{
promoted_type =
(unsigned_operation
- ? lookup_unsigned_typename (language, gdbarch, "int")
- : lookup_signed_typename (language, gdbarch, "int"));
+ ? lookup_unsigned_typename (language, "int")
+ : lookup_signed_typename (language, "int"));
}
else if (result_len <= TYPE_LENGTH (lookup_signed_typename
- (language, gdbarch, "long")))
+ (language, "long")))
{
promoted_type =
(unsigned_operation
- ? lookup_unsigned_typename (language, gdbarch, "long")
- : lookup_signed_typename (language, gdbarch,"long"));
+ ? lookup_unsigned_typename (language, "long")
+ : lookup_signed_typename (language,"long"));
}
break;
default:
}
}
-/* Constructs a fake method with the given parameter types.
- This function is used by the parser to construct an "expected"
- type for method overload resolution. */
+/* Represents a fake method with the given parameter types. This is
+ used by the parser to construct a temporary "expected" type for
+ method overload resolution. FLAGS is used as instance flags of the
+ new type, in order to be able to make the new type represent a
+ const/volatile overload. */
-static struct type *
-make_params (int num_types, struct type **param_types)
+class fake_method
{
- struct type *type = XCNEW (struct type);
- TYPE_MAIN_TYPE (type) = XCNEW (struct main_type);
+public:
+ fake_method (type_instance_flags flags,
+ int num_types, struct type **param_types);
+ ~fake_method ();
+
+ /* The constructed type. */
+ struct type *type () { return &m_type; }
+
+private:
+ struct type m_type {};
+ main_type m_main_type {};
+};
+
+fake_method::fake_method (type_instance_flags flags,
+ int num_types, struct type **param_types)
+{
+ struct type *type = &m_type;
+
+ TYPE_MAIN_TYPE (type) = &m_main_type;
TYPE_LENGTH (type) = 1;
TYPE_CODE (type) = TYPE_CODE_METHOD;
TYPE_CHAIN (type) = type;
+ TYPE_INSTANCE_FLAGS (type) = flags;
if (num_types > 0)
{
if (param_types[num_types - 1] == NULL)
}
}
+ /* We don't use TYPE_ZALLOC here to allocate space as TYPE is owned by
+ neither an objfile nor a gdbarch. As a result we must manually
+ allocate memory for auxiliary fields, and free the memory ourselves
+ when we are done with it. */
TYPE_NFIELDS (type) = num_types;
TYPE_FIELDS (type) = (struct field *)
- TYPE_ZALLOC (type, sizeof (struct field) * num_types);
+ xzalloc (sizeof (struct field) * num_types);
while (num_types-- > 0)
TYPE_FIELD_TYPE (type, num_types) = param_types[num_types];
+}
+
+fake_method::~fake_method ()
+{
+ xfree (TYPE_FIELDS (&m_type));
+}
- return type;
+/* Helper for evaluating an OP_VAR_VALUE. */
+
+value *
+evaluate_var_value (enum noside noside, const block *blk, symbol *var)
+{
+ /* JYG: We used to just return value_zero of the symbol type if
+ we're asked to avoid side effects. Otherwise we return
+ value_of_variable (...). However I'm not sure if
+ value_of_variable () has any side effect. We need a full value
+ object returned here for whatis_exp () to call evaluate_type ()
+ and then pass the full value to value_rtti_target_type () if we
+ are dealing with a pointer or reference to a base class and print
+ object is on. */
+
+ struct value *ret = NULL;
+
+ try
+ {
+ ret = value_of_variable (var, blk);
+ }
+
+ catch (const gdb_exception_error &except)
+ {
+ if (noside != EVAL_AVOID_SIDE_EFFECTS)
+ throw;
+
+ ret = value_zero (SYMBOL_TYPE (var), not_lval);
+ }
+
+ return ret;
}
/* Helper for evaluating an OP_VAR_MSYM_VALUE. */
-static value *
+value *
evaluate_var_msym_value (enum noside noside,
struct objfile *objfile, minimal_symbol *msymbol)
{
+ CORE_ADDR address;
+ type *the_type = find_minsym_type_and_address (msymbol, objfile, &address);
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS && !TYPE_GNU_IFUNC (the_type))
+ return value_zero (the_type, not_lval);
+ else
+ 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);
+}
+
+/* Evaluate a function call. The function to be called is in
+ ARGVEC[0] and the arguments passed to the function are in
+ ARGVEC[1..NARGS]. FUNCTION_NAME is the name of the function, if
+ known. DEFAULT_RETURN_TYPE is used as the function's return type
+ if the return type is unknown. */
+
+static value *
+eval_call (expression *exp, enum noside noside,
+ int nargs, value **argvec,
+ const char *function_name,
+ type *default_return_type)
+{
+ if (argvec[0] == NULL)
+ error (_("Cannot evaluate function -- may be inlined"));
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
- type *the_type = find_minsym_type_and_address (msymbol, objfile, NULL);
- return value_zero (the_type, not_lval);
+ /* If the return type doesn't look like a function type,
+ call an error. This can happen if somebody tries to turn
+ a variable into a function call. */
+
+ type *ftype = value_type (argvec[0]);
+
+ if (TYPE_CODE (ftype) == TYPE_CODE_INTERNAL_FUNCTION)
+ {
+ /* We don't know anything about what the internal
+ function might return, but we have to return
+ something. */
+ return value_zero (builtin_type (exp->gdbarch)->builtin_int,
+ not_lval);
+ }
+ else if (TYPE_CODE (ftype) == TYPE_CODE_XMETHOD)
+ {
+ type *return_type
+ = result_type_of_xmethod (argvec[0],
+ gdb::make_array_view (argvec + 1,
+ nargs));
+
+ if (return_type == NULL)
+ error (_("Xmethod is missing return type."));
+ return value_zero (return_type, not_lval);
+ }
+ else if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
+ || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+ {
+ if (TYPE_GNU_IFUNC (ftype))
+ {
+ CORE_ADDR address = value_address (argvec[0]);
+ type *resolved_type = find_gnu_ifunc_target_type (address);
+
+ if (resolved_type != NULL)
+ ftype = resolved_type;
+ }
+
+ type *return_type = TYPE_TARGET_TYPE (ftype);
+
+ if (return_type == NULL)
+ return_type = default_return_type;
+
+ if (return_type == NULL)
+ error_call_unknown_return_type (function_name);
+
+ return allocate_value (return_type);
+ }
+ else
+ error (_("Expression of type other than "
+ "\"Function returning ...\" used as function"));
}
- else
+ switch (TYPE_CODE (value_type (argvec[0])))
{
- CORE_ADDR address;
- type *the_type = find_minsym_type_and_address (msymbol, objfile, &address);
- return value_at_lazy (the_type, address);
+ case TYPE_CODE_INTERNAL_FUNCTION:
+ return call_internal_function (exp->gdbarch, exp->language_defn,
+ argvec[0], nargs, argvec + 1);
+ case TYPE_CODE_XMETHOD:
+ return call_xmethod (argvec[0], gdb::make_array_view (argvec + 1, nargs));
+ default:
+ return call_function_by_hand (argvec[0], default_return_type,
+ gdb::make_array_view (argvec + 1, nargs));
}
}
-/* Helper for returning a value when handling EVAL_SKIP. */
+/* Helper for evaluating an OP_FUNCALL. */
static value *
-eval_skip_value (expression *exp)
+evaluate_funcall (type *expect_type, expression *exp, int *pos,
+ enum noside noside)
{
- return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
+ int tem;
+ int pc2 = 0;
+ value *arg1 = NULL;
+ value *arg2 = NULL;
+ int save_pos1;
+ symbol *function = NULL;
+ char *function_name = NULL;
+ const char *var_func_name = NULL;
+
+ int pc = (*pos);
+ (*pos) += 2;
+
+ exp_opcode op = exp->elts[*pos].opcode;
+ int nargs = longest_to_int (exp->elts[pc].longconst);
+ /* Allocate arg vector, including space for the function to be
+ called in argvec[0], a potential `this', and a terminating
+ NULL. */
+ value **argvec = (value **) alloca (sizeof (value *) * (nargs + 3));
+ if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
+ {
+ /* First, evaluate the structure into arg2. */
+ pc2 = (*pos)++;
+
+ if (op == STRUCTOP_MEMBER)
+ {
+ arg2 = evaluate_subexp_for_address (exp, pos, noside);
+ }
+ else
+ {
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ }
+
+ /* If the function is a virtual function, then the aggregate
+ value (providing the structure) plays its part by providing
+ the vtable. Otherwise, it is just along for the ride: call
+ the function directly. */
+
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ type *a1_type = check_typedef (value_type (arg1));
+ if (noside == EVAL_SKIP)
+ tem = 1; /* Set it to the right arg index so that all
+ arguments can also be skipped. */
+ else if (TYPE_CODE (a1_type) == TYPE_CODE_METHODPTR)
+ {
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ arg1 = value_zero (TYPE_TARGET_TYPE (a1_type), not_lval);
+ else
+ arg1 = cplus_method_ptr_to_value (&arg2, arg1);
+
+ /* Now, say which argument to start evaluating from. */
+ nargs++;
+ tem = 2;
+ argvec[1] = arg2;
+ }
+ else if (TYPE_CODE (a1_type) == TYPE_CODE_MEMBERPTR)
+ {
+ struct type *type_ptr
+ = lookup_pointer_type (TYPE_SELF_TYPE (a1_type));
+ struct type *target_type_ptr
+ = lookup_pointer_type (TYPE_TARGET_TYPE (a1_type));
+
+ /* Now, convert these values to an address. */
+ arg2 = value_cast (type_ptr, arg2);
+
+ long mem_offset = value_as_long (arg1);
+
+ arg1 = value_from_pointer (target_type_ptr,
+ value_as_long (arg2) + mem_offset);
+ arg1 = value_ind (arg1);
+ tem = 1;
+ }
+ else
+ error (_("Non-pointer-to-member value used in pointer-to-member "
+ "construct"));
+ }
+ else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
+ {
+ /* Hair for method invocations. */
+ int tem2;
+
+ nargs++;
+ /* First, evaluate the structure into arg2. */
+ pc2 = (*pos)++;
+ tem2 = longest_to_int (exp->elts[pc2 + 1].longconst);
+ *pos += 3 + BYTES_TO_EXP_ELEM (tem2 + 1);
+
+ if (op == STRUCTOP_STRUCT)
+ {
+ /* If v is a variable in a register, and the user types
+ v.method (), this will produce an error, because v has no
+ address.
+
+ A possible way around this would be to allocate a copy of
+ the variable on the stack, copy in the contents, call the
+ function, and copy out the contents. I.e. convert this
+ from call by reference to call by copy-return (or
+ whatever it's called). However, this does not work
+ because it is not the same: the method being called could
+ stash a copy of the address, and then future uses through
+ that address (after the method returns) would be expected
+ to use the variable itself, not some copy of it. */
+ arg2 = evaluate_subexp_for_address (exp, pos, noside);
+ }
+ else
+ {
+ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ /* Check to see if the operator '->' has been overloaded.
+ If the operator has been overloaded replace arg2 with the
+ value returned by the custom operator and continue
+ evaluation. */
+ while (unop_user_defined_p (op, arg2))
+ {
+ struct value *value = NULL;
+ try
+ {
+ value = value_x_unop (arg2, op, noside);
+ }
+
+ catch (const gdb_exception_error &except)
+ {
+ if (except.error == NOT_FOUND_ERROR)
+ break;
+ else
+ throw;
+ }
+
+ arg2 = value;
+ }
+ }
+ /* Now, say which argument to start evaluating from. */
+ tem = 2;
+ }
+ else if (op == OP_SCOPE
+ && overload_resolution
+ && (exp->language_defn->la_language == language_cplus))
+ {
+ /* Unpack it locally so we can properly handle overload
+ resolution. */
+ char *name;
+ int local_tem;
+
+ pc2 = (*pos)++;
+ local_tem = longest_to_int (exp->elts[pc2 + 2].longconst);
+ (*pos) += 4 + BYTES_TO_EXP_ELEM (local_tem + 1);
+ struct type *type = exp->elts[pc2 + 1].type;
+ name = &exp->elts[pc2 + 3].string;
+
+ function = NULL;
+ function_name = NULL;
+ if (TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
+ {
+ function = cp_lookup_symbol_namespace (TYPE_NAME (type),
+ name,
+ get_selected_block (0),
+ VAR_DOMAIN).symbol;
+ if (function == NULL)
+ error (_("No symbol \"%s\" in namespace \"%s\"."),
+ name, TYPE_NAME (type));
+
+ tem = 1;
+ /* arg2 is left as NULL on purpose. */
+ }
+ else
+ {
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION);
+ function_name = name;
+
+ /* We need a properly typed value for method lookup. For
+ static methods arg2 is otherwise unused. */
+ arg2 = value_zero (type, lval_memory);
+ ++nargs;
+ tem = 2;
+ }
+ }
+ else if (op == OP_ADL_FUNC)
+ {
+ /* Save the function position and move pos so that the arguments
+ can be evaluated. */
+ int func_name_len;
+
+ save_pos1 = *pos;
+ tem = 1;
+
+ func_name_len = longest_to_int (exp->elts[save_pos1 + 3].longconst);
+ (*pos) += 6 + BYTES_TO_EXP_ELEM (func_name_len + 1);
+ }
+ else
+ {
+ /* Non-method function call. */
+ save_pos1 = *pos;
+ tem = 1;
+
+ /* If this is a C++ function wait until overload resolution. */
+ if (op == OP_VAR_VALUE
+ && overload_resolution
+ && (exp->language_defn->la_language == language_cplus))
+ {
+ (*pos) += 4; /* Skip the evaluation of the symbol. */
+ argvec[0] = NULL;
+ }
+ else
+ {
+ if (op == OP_VAR_MSYM_VALUE)
+ {
+ minimal_symbol *msym = exp->elts[*pos + 2].msymbol;
+ var_func_name = msym->print_name ();
+ }
+ else if (op == OP_VAR_VALUE)
+ {
+ symbol *sym = exp->elts[*pos + 2].symbol;
+ var_func_name = sym->print_name ();
+ }
+
+ argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside);
+ type *type = value_type (argvec[0]);
+ if (type && TYPE_CODE (type) == TYPE_CODE_PTR)
+ type = TYPE_TARGET_TYPE (type);
+ if (type && TYPE_CODE (type) == TYPE_CODE_FUNC)
+ {
+ for (; tem <= nargs && tem <= TYPE_NFIELDS (type); tem++)
+ {
+ argvec[tem] = evaluate_subexp (TYPE_FIELD_TYPE (type,
+ tem - 1),
+ exp, pos, noside);
+ }
+ }
+ }
+ }
+
+ /* Evaluate arguments (if not already done, e.g., namespace::func()
+ and overload-resolution is off). */
+ for (; tem <= nargs; tem++)
+ {
+ /* Ensure that array expressions are coerced into pointer
+ objects. */
+ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+ }
+
+ /* Signal end of arglist. */
+ argvec[tem] = 0;
+
+ if (noside == EVAL_SKIP)
+ return eval_skip_value (exp);
+
+ if (op == OP_ADL_FUNC)
+ {
+ struct symbol *symp;
+ char *func_name;
+ int name_len;
+ int string_pc = save_pos1 + 3;
+
+ /* Extract the function name. */
+ name_len = longest_to_int (exp->elts[string_pc].longconst);
+ func_name = (char *) alloca (name_len + 1);
+ strcpy (func_name, &exp->elts[string_pc + 1].string);
+
+ find_overload_match (gdb::make_array_view (&argvec[1], nargs),
+ func_name,
+ NON_METHOD, /* not method */
+ NULL, NULL, /* pass NULL symbol since
+ symbol is unknown */
+ NULL, &symp, NULL, 0, noside);
+
+ /* Now fix the expression being evaluated. */
+ exp->elts[save_pos1 + 2].symbol = symp;
+ argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);
+ }
+
+ if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR
+ || (op == OP_SCOPE && function_name != NULL))
+ {
+ int static_memfuncp;
+ char *tstr;
+
+ /* Method invocation: stuff "this" as first parameter. If the
+ method turns out to be static we undo this below. */
+ argvec[1] = arg2;
+
+ if (op != OP_SCOPE)
+ {
+ /* Name of method from expression. */
+ tstr = &exp->elts[pc2 + 2].string;
+ }
+ else
+ tstr = function_name;
+
+ if (overload_resolution && (exp->language_defn->la_language
+ == language_cplus))
+ {
+ /* Language is C++, do some overload resolution before
+ evaluation. */
+ struct value *valp = NULL;
+
+ (void) find_overload_match (gdb::make_array_view (&argvec[1], nargs),
+ tstr,
+ METHOD, /* method */
+ &arg2, /* the object */
+ NULL, &valp, NULL,
+ &static_memfuncp, 0, noside);
+
+ if (op == OP_SCOPE && !static_memfuncp)
+ {
+ /* For the time being, we don't handle this. */
+ error (_("Call to overloaded function %s requires "
+ "`this' pointer"),
+ function_name);
+ }
+ argvec[1] = arg2; /* the ``this'' pointer */
+ argvec[0] = valp; /* Use the method found after overload
+ resolution. */
+ }
+ else
+ /* Non-C++ case -- or no overload resolution. */
+ {
+ struct value *temp = arg2;
+
+ argvec[0] = value_struct_elt (&temp, argvec + 1, tstr,
+ &static_memfuncp,
+ op == STRUCTOP_STRUCT
+ ? "structure" : "structure pointer");
+ /* value_struct_elt updates temp with the correct value of
+ the ``this'' pointer if necessary, so modify argvec[1] to
+ reflect any ``this'' changes. */
+ arg2
+ = value_from_longest (lookup_pointer_type(value_type (temp)),
+ value_address (temp)
+ + value_embedded_offset (temp));
+ argvec[1] = arg2; /* the ``this'' pointer */
+ }
+
+ /* Take out `this' if needed. */
+ if (static_memfuncp)
+ {
+ argvec[1] = argvec[0];
+ nargs--;
+ argvec++;
+ }
+ }
+ else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
+ {
+ /* Pointer to member. argvec[1] is already set up. */
+ argvec[0] = arg1;
+ }
+ else if (op == OP_VAR_VALUE || (op == OP_SCOPE && function != NULL))
+ {
+ /* Non-member function being called. */
+ /* fn: This can only be done for C++ functions. A C-style
+ function in a C++ program, for instance, does not have the
+ fields that are expected here. */
+
+ if (overload_resolution && (exp->language_defn->la_language
+ == language_cplus))
+ {
+ /* Language is C++, do some overload resolution before
+ evaluation. */
+ struct symbol *symp;
+ int no_adl = 0;
+
+ /* If a scope has been specified disable ADL. */
+ if (op == OP_SCOPE)
+ no_adl = 1;
+
+ if (op == OP_VAR_VALUE)
+ function = exp->elts[save_pos1+2].symbol;
+
+ (void) find_overload_match (gdb::make_array_view (&argvec[1], nargs),
+ NULL, /* no need for name */
+ NON_METHOD, /* not method */
+ NULL, function, /* the function */
+ NULL, &symp, NULL, no_adl, noside);
+
+ if (op == OP_VAR_VALUE)
+ {
+ /* Now fix the expression being evaluated. */
+ exp->elts[save_pos1+2].symbol = symp;
+ argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1,
+ noside);
+ }
+ else
+ argvec[0] = value_of_variable (symp, get_selected_block (0));
+ }
+ else
+ {
+ /* Not C++, or no overload resolution allowed. */
+ /* Nothing to be done; argvec already correctly set up. */
+ }
+ }
+ else
+ {
+ /* It is probably a C-style function. */
+ /* Nothing to be done; argvec already correctly set up. */
+ }
+
+ return eval_call (exp, noside, nargs, argvec, var_func_name, expect_type);
+}
+
+/* Helper for skipping all the arguments in an undetermined argument list.
+ This function was designed for use in the OP_F77_UNDETERMINED_ARGLIST
+ case of evaluate_subexp_standard as multiple, but not all, code paths
+ require a generic skip. */
+
+static void
+skip_undetermined_arglist (int nargs, struct expression *exp, int *pos,
+ enum noside noside)
+{
+ for (int i = 0; i < nargs; ++i)
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
}
struct value *
{
enum exp_opcode op;
int tem, tem2, tem3;
- int pc, pc2 = 0, oldpos;
+ int pc, oldpos;
struct value *arg1 = NULL;
struct value *arg2 = NULL;
struct value *arg3;
int ix;
long mem_offset;
struct type **arg_types;
- int save_pos1;
- struct symbol *function = NULL;
- char *function_name = NULL;
- const char *var_func_name = NULL;
pc = (*pos)++;
op = exp->elts[pc].opcode;
return value_from_longest (exp->elts[pc + 1].type,
exp->elts[pc + 2].longconst);
- case OP_DOUBLE:
+ case OP_FLOAT:
(*pos) += 3;
- return value_from_double (exp->elts[pc + 1].type,
- exp->elts[pc + 2].doubleconst);
-
- case OP_DECFLOAT:
- (*pos) += 3;
- return value_from_decfloat (exp->elts[pc + 1].type,
- exp->elts[pc + 2].decfloatconst);
+ return value_from_contents (exp->elts[pc + 1].type,
+ exp->elts[pc + 2].floatconst);
case OP_ADL_FUNC:
case OP_VAR_VALUE:
- (*pos) += 3;
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
-
- /* JYG: We used to just return value_zero of the symbol type
- if we're asked to avoid side effects. Otherwise we return
- value_of_variable (...). However I'm not sure if
- value_of_variable () has any side effect.
- We need a full value object returned here for whatis_exp ()
- to call evaluate_type () and then pass the full value to
- value_rtti_target_type () if we are dealing with a pointer
- or reference to a base class and print object is on. */
-
{
- struct value *ret = NULL;
-
- TRY
+ (*pos) += 3;
+ symbol *var = exp->elts[pc + 2].symbol;
+ if (TYPE_CODE (SYMBOL_TYPE (var)) == 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
{
- ret = value_of_variable (exp->elts[pc + 2].symbol,
- exp->elts[pc + 1].block);
+ /* 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));
}
+ }
- CATCH (except, RETURN_MASK_ERROR)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- ret = value_zero (SYMBOL_TYPE (exp->elts[pc + 2].symbol),
- not_lval);
- else
- throw_exception (except);
- }
- END_CATCH
+ case OP_VAR_MSYM_VALUE:
+ {
+ (*pos) += 3;
+
+ minimal_symbol *msymbol = exp->elts[pc + 2].msymbol;
+ value *val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ msymbol);
- return ret;
+ type = value_type (val);
+ if (TYPE_CODE (type) == TYPE_CODE_ERROR
+ && (noside != EVAL_AVOID_SIDE_EFFECTS || pc != 0))
+ error_unknown_type (msymbol->print_name ());
+ return val;
}
- case OP_VAR_MSYM_VALUE:
- (*pos) += 3;
- return evaluate_var_msym_value (noside,
- exp->elts[pc + 1].objfile,
- exp->elts[pc + 2].msymbol);
case OP_VAR_ENTRY_VALUE:
(*pos) += 2;
if (SYMBOL_COMPUTED_OPS (sym) == NULL
|| SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry == NULL)
error (_("Symbol \"%s\" does not have any specific entry value"),
- SYMBOL_PRINT_NAME (sym));
+ sym->print_name ());
frame = get_selected_frame (NULL);
return SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry (sym, frame);
}
+ case OP_FUNC_STATIC_VAR:
+ tem = longest_to_int (exp->elts[pc + 1].longconst);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+ if (noside == EVAL_SKIP)
+ return eval_skip_value (exp);
+
+ {
+ value *func = evaluate_subexp_standard (NULL, exp, pos, noside);
+ CORE_ADDR addr = value_address (func);
+
+ const block *blk = block_for_pc (addr);
+ const char *var = &exp->elts[pc + 2].string;
+
+ struct block_symbol sym = lookup_symbol (var, blk, VAR_DOMAIN, NULL);
+
+ if (sym.symbol == NULL)
+ error (_("No symbol \"%s\" in specified context."), var);
+
+ return evaluate_var_value (noside, sym.block, sym.symbol);
+ }
+
case OP_LAST:
(*pos) += 2;
return
So for these registers, we fetch the register value regardless
of the evaluation mode. */
if (noside == EVAL_AVOID_SIDE_EFFECTS
- && regno < gdbarch_num_regs (exp->gdbarch)
- + gdbarch_num_pseudo_regs (exp->gdbarch))
+ && regno < gdbarch_num_cooked_regs (exp->gdbarch))
val = value_zero (register_type (exp->gdbarch, regno), not_lval);
else
val = value_of_register (regno, get_selected_frame (NULL));
{
int bit_index = (unsigned) range_low % TARGET_CHAR_BIT;
- if (gdbarch_bits_big_endian (exp->gdbarch))
+ 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;
only). */
if (gnu_runtime)
{
- struct type *type = selector_type;
+ type = selector_type;
type = lookup_function_type (type);
type = lookup_pointer_type (type);
argvec[3] = value_from_longest (long_type, selector);
argvec[4] = 0;
- ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1);
+ ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
if (gnu_runtime)
{
/* Function objc_msg_lookup returns a pointer. */
argvec[0] = ret;
- ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1);
+ ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
}
if (value_as_long (ret) == 0)
error (_("Target does not respond to this message selector."));
argvec[3] = value_from_longest (long_type, selector);
argvec[4] = 0;
- ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1);
+ ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
if (gnu_runtime)
{
argvec[0] = ret;
- ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1);
+ ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
}
/* ret should now be the selector. */
/* 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,
- ¤t_target);
+ current_top_target ());
/* Is it a high_level symbol? */
sym = find_pc_function (addr);
it's opinion (ie. through "whatis"), it won't offer
it. */
- struct type *type = value_type (called_method);
+ struct type *callee_type = value_type (called_method);
- if (type && TYPE_CODE (type) == TYPE_CODE_PTR)
- type = TYPE_TARGET_TYPE (type);
- type = TYPE_TARGET_TYPE (type);
+ if (callee_type && TYPE_CODE (callee_type) == TYPE_CODE_PTR)
+ callee_type = TYPE_TARGET_TYPE (callee_type);
+ callee_type = TYPE_TARGET_TYPE (callee_type);
- if (type)
+ if (callee_type)
{
- if ((TYPE_CODE (type) == TYPE_CODE_ERROR) && expect_type)
+ if ((TYPE_CODE (callee_type) == TYPE_CODE_ERROR) && expect_type)
return allocate_value (expect_type);
else
- return allocate_value (type);
+ return allocate_value (callee_type);
}
else
error (_("Expression of type other than "
argvec[tem + 3] = evaluate_subexp_with_coercion (exp, pos, noside);
argvec[tem + 3] = 0;
+ auto call_args = gdb::make_array_view (argvec + 1, nargs + 2);
+
if (gnu_runtime && (method != NULL))
{
/* Function objc_msg_lookup returns a pointer. */
deprecated_set_value_type (argvec[0],
lookup_pointer_type (lookup_function_type (value_type (argvec[0]))));
- argvec[0]
- = call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1);
+ argvec[0] = call_function_by_hand (argvec[0], NULL, call_args);
}
- ret = call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1);
- return ret;
+ return call_function_by_hand (argvec[0], NULL, call_args);
}
break;
case OP_FUNCALL:
- (*pos) += 2;
- op = exp->elts[*pos].opcode;
- nargs = longest_to_int (exp->elts[pc + 1].longconst);
- /* Allocate arg vector, including space for the function to be
- called in argvec[0], a potential `this', and a terminating NULL. */
- argvec = (struct value **)
- alloca (sizeof (struct value *) * (nargs + 3));
- if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
- {
- /* First, evaluate the structure into arg2. */
- pc2 = (*pos)++;
-
- if (op == STRUCTOP_MEMBER)
- {
- arg2 = evaluate_subexp_for_address (exp, pos, noside);
- }
- else
- {
- arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- }
-
- /* If the function is a virtual function, then the
- aggregate value (providing the structure) plays
- its part by providing the vtable. Otherwise,
- it is just along for the ride: call the function
- directly. */
-
- arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
-
- 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 (TYPE_CODE (type) == TYPE_CODE_METHODPTR)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- arg1 = value_zero (TYPE_TARGET_TYPE (type), not_lval);
- else
- arg1 = cplus_method_ptr_to_value (&arg2, arg1);
-
- /* Now, say which argument to start evaluating from. */
- nargs++;
- tem = 2;
- argvec[1] = arg2;
- }
- else if (TYPE_CODE (type) == TYPE_CODE_MEMBERPTR)
- {
- struct type *type_ptr
- = lookup_pointer_type (TYPE_SELF_TYPE (type));
- struct type *target_type_ptr
- = lookup_pointer_type (TYPE_TARGET_TYPE (type));
-
- /* Now, convert these values to an address. */
- arg2 = value_cast (type_ptr, arg2);
-
- mem_offset = value_as_long (arg1);
-
- arg1 = value_from_pointer (target_type_ptr,
- value_as_long (arg2) + mem_offset);
- arg1 = value_ind (arg1);
- tem = 1;
- }
- else
- error (_("Non-pointer-to-member value used in pointer-to-member "
- "construct"));
- }
- else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
- {
- /* Hair for method invocations. */
- int tem2;
-
- nargs++;
- /* First, evaluate the structure into arg2. */
- pc2 = (*pos)++;
- tem2 = longest_to_int (exp->elts[pc2 + 1].longconst);
- *pos += 3 + BYTES_TO_EXP_ELEM (tem2 + 1);
-
- if (op == STRUCTOP_STRUCT)
- {
- /* If v is a variable in a register, and the user types
- v.method (), this will produce an error, because v has
- no address.
-
- A possible way around this would be to allocate a
- copy of the variable on the stack, copy in the
- contents, call the function, and copy out the
- contents. I.e. convert this from call by reference
- to call by copy-return (or whatever it's called).
- However, this does not work because it is not the
- same: the method being called could stash a copy of
- the address, and then future uses through that address
- (after the method returns) would be expected to
- use the variable itself, not some copy of it. */
- arg2 = evaluate_subexp_for_address (exp, pos, noside);
- }
- else
- {
- arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
-
- /* Check to see if the operator '->' has been
- overloaded. If the operator has been overloaded
- replace arg2 with the value returned by the custom
- operator and continue evaluation. */
- while (unop_user_defined_p (op, arg2))
- {
- struct value *value = NULL;
- TRY
- {
- value = value_x_unop (arg2, op, noside);
- }
-
- CATCH (except, RETURN_MASK_ERROR)
- {
- if (except.error == NOT_FOUND_ERROR)
- break;
- else
- throw_exception (except);
- }
- END_CATCH
-
- 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);
- type = exp->elts[pc2 + 1].type;
- name = &exp->elts[pc2 + 3].string;
-
- function = NULL;
- function_name = NULL;
- if (TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
- {
- function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
- name,
- get_selected_block (0),
- VAR_DOMAIN).symbol;
- if (function == NULL)
- error (_("No symbol \"%s\" in namespace \"%s\"."),
- name, TYPE_TAG_NAME (type));
-
- tem = 1;
- /* arg2 is left as NULL on purpose. */
- }
- else
- {
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION);
- function_name = name;
-
- /* We need a properly typed value for method lookup. For
- static methods arg2 is otherwise unused. */
- arg2 = value_zero (type, lval_memory);
- ++nargs;
- tem = 2;
- }
- }
- else if (op == OP_ADL_FUNC)
- {
- /* Save the function position and move pos so that the arguments
- can be evaluated. */
- int func_name_len;
-
- save_pos1 = *pos;
- tem = 1;
-
- func_name_len = longest_to_int (exp->elts[save_pos1 + 3].longconst);
- (*pos) += 6 + BYTES_TO_EXP_ELEM (func_name_len + 1);
- }
- else
- {
- /* Non-method function call. */
- save_pos1 = *pos;
- tem = 1;
-
- /* If this is a C++ function wait until overload resolution. */
- if (op == OP_VAR_VALUE
- && overload_resolution
- && (exp->language_defn->la_language == language_cplus))
- {
- (*pos) += 4; /* Skip the evaluation of the symbol. */
- argvec[0] = NULL;
- }
- else
- {
- if (op == OP_VAR_MSYM_VALUE)
- {
- symbol *sym = exp->elts[*pos + 2].symbol;
- var_func_name = SYMBOL_PRINT_NAME (sym);
- }
- else if (op == OP_VAR_VALUE)
- {
- minimal_symbol *msym = exp->elts[*pos + 2].msymbol;
- var_func_name = MSYMBOL_PRINT_NAME (msym);
- }
-
- argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside);
- type = value_type (argvec[0]);
- if (type && TYPE_CODE (type) == TYPE_CODE_PTR)
- type = TYPE_TARGET_TYPE (type);
- if (type && TYPE_CODE (type) == TYPE_CODE_FUNC)
- {
- for (; tem <= nargs && tem <= TYPE_NFIELDS (type); tem++)
- {
- argvec[tem] = evaluate_subexp (TYPE_FIELD_TYPE (type,
- tem - 1),
- exp, pos, noside);
- }
- }
- }
- }
-
- /* Evaluate arguments (if not already done, e.g., namespace::func()
- and overload-resolution is off). */
- for (; tem <= nargs; tem++)
- {
- /* Ensure that array expressions are coerced into pointer
- objects. */
- argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
- }
-
- /* Signal end of arglist. */
- argvec[tem] = 0;
-
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
-
- if (op == OP_ADL_FUNC)
- {
- struct symbol *symp;
- char *func_name;
- int name_len;
- int string_pc = save_pos1 + 3;
-
- /* Extract the function name. */
- name_len = longest_to_int (exp->elts[string_pc].longconst);
- func_name = (char *) alloca (name_len + 1);
- strcpy (func_name, &exp->elts[string_pc + 1].string);
-
- find_overload_match (&argvec[1], nargs, func_name,
- NON_METHOD, /* not method */
- NULL, NULL, /* pass NULL symbol since
- symbol is unknown */
- NULL, &symp, NULL, 0, noside);
-
- /* Now fix the expression being evaluated. */
- exp->elts[save_pos1 + 2].symbol = symp;
- argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);
- }
-
- if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR
- || (op == OP_SCOPE && function_name != NULL))
- {
- int static_memfuncp;
- char *tstr;
-
- /* Method invocation: stuff "this" as first parameter.
- If the method turns out to be static we undo this below. */
- argvec[1] = arg2;
-
- if (op != OP_SCOPE)
- {
- /* Name of method from expression. */
- tstr = &exp->elts[pc2 + 2].string;
- }
- else
- tstr = function_name;
-
- if (overload_resolution && (exp->language_defn->la_language
- == language_cplus))
- {
- /* Language is C++, do some overload resolution before
- evaluation. */
- struct value *valp = NULL;
-
- (void) find_overload_match (&argvec[1], nargs, tstr,
- METHOD, /* method */
- &arg2, /* the object */
- NULL, &valp, NULL,
- &static_memfuncp, 0, noside);
-
- if (op == OP_SCOPE && !static_memfuncp)
- {
- /* For the time being, we don't handle this. */
- error (_("Call to overloaded function %s requires "
- "`this' pointer"),
- function_name);
- }
- argvec[1] = arg2; /* the ``this'' pointer */
- argvec[0] = valp; /* Use the method found after overload
- resolution. */
- }
- else
- /* Non-C++ case -- or no overload resolution. */
- {
- struct value *temp = arg2;
-
- argvec[0] = value_struct_elt (&temp, argvec + 1, tstr,
- &static_memfuncp,
- op == STRUCTOP_STRUCT
- ? "structure" : "structure pointer");
- /* value_struct_elt updates temp with the correct value
- of the ``this'' pointer if necessary, so modify argvec[1] to
- reflect any ``this'' changes. */
- arg2
- = value_from_longest (lookup_pointer_type(value_type (temp)),
- value_address (temp)
- + value_embedded_offset (temp));
- argvec[1] = arg2; /* the ``this'' pointer */
- }
-
- /* Take out `this' if needed. */
- if (static_memfuncp)
- {
- argvec[1] = argvec[0];
- nargs--;
- argvec++;
- }
- }
- else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
- {
- /* Pointer to member. argvec[1] is already set up. */
- argvec[0] = arg1;
- }
- else if (op == OP_VAR_VALUE || (op == OP_SCOPE && function != NULL))
- {
- /* Non-member function being called. */
- /* fn: This can only be done for C++ functions. A C-style function
- in a C++ program, for instance, does not have the fields that
- are expected here. */
-
- if (overload_resolution && (exp->language_defn->la_language
- == language_cplus))
- {
- /* Language is C++, do some overload resolution before
- evaluation. */
- struct symbol *symp;
- int no_adl = 0;
-
- /* If a scope has been specified disable ADL. */
- if (op == OP_SCOPE)
- no_adl = 1;
-
- if (op == OP_VAR_VALUE)
- function = exp->elts[save_pos1+2].symbol;
-
- (void) find_overload_match (&argvec[1], nargs,
- NULL, /* no need for name */
- NON_METHOD, /* not method */
- NULL, function, /* the function */
- NULL, &symp, NULL, no_adl, noside);
-
- if (op == OP_VAR_VALUE)
- {
- /* Now fix the expression being evaluated. */
- exp->elts[save_pos1+2].symbol = symp;
- argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1,
- noside);
- }
- else
- argvec[0] = value_of_variable (symp, get_selected_block (0));
- }
- else
- {
- /* Not C++, or no overload resolution allowed. */
- /* Nothing to be done; argvec already correctly set up. */
- }
- }
- else
- {
- /* It is probably a C-style function. */
- /* Nothing to be done; argvec already correctly set up. */
- }
-
- do_call_it:
-
- if (argvec[0] == NULL)
- error (_("Cannot evaluate function -- may be inlined"));
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- /* If the return type doesn't look like a function type,
- call an error. This can happen if somebody tries to turn
- a variable into a function call. */
-
- struct type *ftype = value_type (argvec[0]);
-
- if (TYPE_CODE (ftype) == TYPE_CODE_INTERNAL_FUNCTION)
- {
- /* We don't know anything about what the internal
- function might return, but we have to return
- something. */
- return value_zero (builtin_type (exp->gdbarch)->builtin_int,
- not_lval);
- }
- else if (TYPE_CODE (ftype) == TYPE_CODE_XMETHOD)
- {
- struct type *return_type
- = result_type_of_xmethod (argvec[0], nargs, argvec + 1);
-
- if (return_type == NULL)
- error (_("Xmethod is missing return type."));
- return value_zero (return_type, not_lval);
- }
- else if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
- || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
- {
- struct type *return_type = TYPE_TARGET_TYPE (ftype);
-
- if (return_type == NULL)
- return_type = expect_type;
-
- if (return_type == NULL)
- error_call_unknown_return_type (var_func_name);
-
- return allocate_value (return_type);
- }
- else
- error (_("Expression of type other than "
- "\"Function returning ...\" used as function"));
- }
- switch (TYPE_CODE (value_type (argvec[0])))
- {
- case TYPE_CODE_INTERNAL_FUNCTION:
- return call_internal_function (exp->gdbarch, exp->language_defn,
- argvec[0], nargs, argvec + 1);
- case TYPE_CODE_XMETHOD:
- return call_xmethod (argvec[0], nargs, argvec + 1);
- default:
- return call_function_by_hand (argvec[0],
- expect_type, nargs, argvec + 1);
- }
- /* pai: FIXME save value from call_function_by_hand, then adjust
- pc by adjust_fn_pc if +ve. */
+ return evaluate_funcall (expect_type, exp, pos, noside);
case OP_F77_UNDETERMINED_ARGLIST:
if (exp->elts[*pos].opcode == OP_RANGE)
return value_f90_subarray (arg1, exp, pos, noside);
else
- goto multi_f77_subscript;
+ {
+ if (noside == EVAL_SKIP)
+ {
+ skip_undetermined_arglist (nargs, exp, pos, noside);
+ /* Return the dummy value with the correct type. */
+ return arg1;
+ }
+ goto multi_f77_subscript;
+ }
case TYPE_CODE_STRING:
if (exp->elts[*pos].opcode == OP_RANGE)
return value_f90_subarray (arg1, exp, pos, noside);
else
{
+ if (noside == EVAL_SKIP)
+ {
+ skip_undetermined_arglist (nargs, exp, pos, noside);
+ /* Return the dummy value with the correct type. */
+ return arg1;
+ }
arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
return value_subscript (arg1, value_as_long (arg2));
}
case TYPE_CODE_PTR:
case TYPE_CODE_FUNC:
+ case TYPE_CODE_INTERNAL_FUNCTION:
/* It's a function call. */
/* Allocate arg vector, including space for the function to be
called in argvec[0] and a terminating NULL. */
argvec[0] = arg1;
tem = 1;
for (; tem <= nargs; tem++)
- argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+ {
+ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+ /* Arguments in Fortran are passed by address. Coerce the
+ arguments here rather than in value_arg_coerce as otherwise
+ the call to malloc to place the non-lvalue parameters in
+ target memory is hit by this Fortran specific logic. This
+ results in malloc being called with a pointer to an integer
+ followed by an attempt to malloc the arguments to malloc in
+ target memory. Infinite recursion ensues. */
+ if (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC)
+ {
+ bool is_artificial
+ = TYPE_FIELD_ARTIFICIAL (value_type (arg1), tem - 1);
+ argvec[tem] = fortran_argument_convert (argvec[tem],
+ is_artificial);
+ }
+ }
argvec[tem] = 0; /* signal end of arglist */
if (noside == EVAL_SKIP)
return eval_skip_value (exp);
- goto do_call_it;
+ return eval_call (exp, noside, nargs, argvec, NULL, expect_type);
default:
error (_("Cannot perform substring on this type"));
while (unop_user_defined_p (op, arg1))
{
struct value *value = NULL;
- TRY
+ try
{
value = value_x_unop (arg1, op, noside);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
if (except.error == NOT_FOUND_ERROR)
break;
else
- throw_exception (except);
+ throw;
}
- END_CATCH
arg1 = value;
}
with rtti type in order to continue on with successful
lookup of member / method only available in the rtti type. */
{
- struct type *type = value_type (arg1);
+ struct type *arg_type = value_type (arg1);
struct type *real_type;
int full, using_enc;
LONGEST top;
struct value_print_options opts;
get_user_print_options (&opts);
- if (opts.objectprint && TYPE_TARGET_TYPE(type)
- && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
+ if (opts.objectprint && TYPE_TARGET_TYPE (arg_type)
+ && (TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_STRUCT))
{
real_type = value_rtti_indirect_type (arg1, &full, &top,
&using_enc);
}
case TYPE_INSTANCE:
- nargs = longest_to_int (exp->elts[pc + 1].longconst);
- arg_types = (struct type **) alloca (nargs * sizeof (struct type *));
- for (ix = 0; ix < nargs; ++ix)
- arg_types[ix] = exp->elts[pc + 1 + ix + 1].type;
-
- expect_type = make_params (nargs, arg_types);
- *(pos) += 3 + nargs;
- arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
- xfree (TYPE_FIELDS (expect_type));
- xfree (TYPE_MAIN_TYPE (expect_type));
- xfree (expect_type);
- return arg1;
+ {
+ type_instance_flags flags
+ = (type_instance_flag_value) longest_to_int (exp->elts[pc + 1].longconst);
+ nargs = longest_to_int (exp->elts[pc + 2].longconst);
+ arg_types = (struct type **) alloca (nargs * sizeof (struct type *));
+ for (ix = 0; ix < nargs; ++ix)
+ arg_types[ix] = exp->elts[pc + 2 + ix + 1].type;
+
+ fake_method fake_expect_type (flags, nargs, arg_types);
+ *(pos) += 4 + nargs;
+ return evaluate_subexp_standard (fake_expect_type.type (), exp, pos,
+ noside);
+ }
case BINOP_CONCAT:
arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
case BINOP_ASSIGN:
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- arg2 = evaluate_subexp (value_type (arg1), 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
+ ? NULL_TYPE : value_type (arg1),
+ exp, pos, noside);
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
}
return evaluate_subexp_for_sizeof (exp, pos, noside);
+ case UNOP_ALIGNOF:
+ {
+ type = value_type (evaluate_subexp (NULL_TYPE, exp, pos,
+ EVAL_AVOID_SIDE_EFFECTS));
+ /* FIXME: This should be size_t. */
+ struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
+ ULONGEST align = type_align (type);
+ if (align == 0)
+ error (_("could not determine alignment of type"));
+ return value_from_longest (size_type, align);
+ }
+
case UNOP_CAST:
(*pos) += 2;
type = exp->elts[pc + 1].type;
- arg1 = evaluate_subexp (type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
- if (type != value_type (arg1))
- arg1 = value_cast (type, arg1);
- return arg1;
+ 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);
- arg1 = evaluate_subexp (type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
- if (type != value_type (arg1))
- arg1 = value_cast (type, arg1);
- return arg1;
+ return evaluate_subexp_for_cast (exp, pos, noside, type);
case UNOP_DYNAMIC_CAST:
arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
else
return value_at_lazy (type, value_as_address (arg1));
- case UNOP_MEMVAL_TLS:
- (*pos) += 3;
- arg1 = evaluate_subexp (expect_type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (exp->elts[pc + 2].type, lval_memory);
- else
- {
- CORE_ADDR tls_addr;
-
- tls_addr = target_translate_tls_address (exp->elts[pc + 1].objfile,
- value_as_address (arg1));
- return value_at_lazy (exp->elts[pc + 2].type, tls_addr);
- }
-
case UNOP_PREINCREMENT:
arg1 = evaluate_subexp (expect_type, exp, pos, noside);
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
|| sub_op == STRUCTOP_PTR
|| sub_op == OP_SCOPE))
{
- struct type *type = value_type (result);
+ type = value_type (result);
if (!TYPE_IS_REFERENCE (type))
{
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);
{
val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
type = value_type (val);
+ if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && is_dynamic_type (TYPE_INDEX_TYPE (type))
+ && TYPE_HIGH_BOUND_UNDEFINED (TYPE_INDEX_TYPE (type)))
+ 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) == 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 subcription to allow
+ must re-evaluate the right hand side of the subscription to allow
side-effects. */
case BINOP_SUBSCRIPT:
if (noside == EVAL_NORMAL)
{
- int pc = (*pos) + 1;
+ int npc = (*pos) + 1;
- val = evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
+ val = evaluate_subexp (NULL_TYPE, exp, &npc, EVAL_AVOID_SIDE_EFFECTS);
type = check_typedef (value_type (val));
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
{
return value_from_longest (size_type, (LONGEST) 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)
+{
+ int pc = *pos;
+
+ /* Don't let symbols be evaluated with evaluate_subexp because that
+ throws an "unknown type" error for no-debug data symbols.
+ Instead, we want the cast to reinterpret the symbol. */
+ if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE
+ || exp->elts[pc].opcode == OP_VAR_VALUE)
+ {
+ (*pos) += 4;
+
+ value *val;
+ if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE)
+ {
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (to_type, not_lval);
+
+ val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ exp->elts[pc + 2].msymbol);
+ }
+ else
+ val = evaluate_var_value (noside,
+ exp->elts[pc + 1].block,
+ exp->elts[pc + 2].symbol);
+
+ if (noside == EVAL_SKIP)
+ return eval_skip_value (exp);
+
+ val = value_cast (to_type, val);
+
+ /* Don't allow e.g. '&(int)var_with_no_debug_info'. */
+ if (VALUE_LVAL (val) == lval_memory)
+ {
+ if (value_lazy (val))
+ value_fetch_lazy (val);
+ VALUE_LVAL (val) = not_lval;
+ }
+ return val;
+ }
+
+ value *val = evaluate_subexp (to_type, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ return eval_skip_value (exp);
+ return value_cast (to_type, val);
+}
+
/* Parse a type expression in the string [P..P+LENGTH). */
struct type *