/* Evaluate expressions for GDB.
- Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 97, 1998
- Free Software Foundation, Inc.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
+ Foundation, Inc.
This file is part of GDB.
#include "expression.h"
#include "target.h"
#include "frame.h"
-#include "demangle.h"
#include "language.h" /* For CAST_IS_CONVERSION */
#include "f-lang.h" /* for array bound stuff */
+#include "cp-abi.h"
/* Defined in symtab.c */
extern int hp_som_som_object_present;
/* This is defined in valops.c */
extern int overload_resolution;
+/* JYG: lookup rtti type of STRUCTOP_PTR when this is set to continue
+ on with successful lookup for member/method of the rtti type. */
+extern int objectprint;
/* Prototypes for local functions. */
-static value_ptr evaluate_subexp_for_sizeof PARAMS ((struct expression *,
- int *));
+static struct value *evaluate_subexp_for_sizeof (struct expression *, int *);
-static value_ptr evaluate_subexp_for_address PARAMS ((struct expression *,
- int *, enum noside));
+static struct value *evaluate_subexp_for_address (struct expression *,
+ int *, enum noside);
-static value_ptr evaluate_subexp PARAMS ((struct type *, struct expression *,
- int *, enum noside));
+static struct value *evaluate_subexp (struct type *, struct expression *,
+ int *, enum noside);
-static char *get_label PARAMS ((struct expression *, int *));
+static char *get_label (struct expression *, int *);
-static value_ptr
- evaluate_struct_tuple PARAMS ((value_ptr, struct expression *, int *,
- enum noside, int));
+static struct value *evaluate_struct_tuple (struct value *,
+ struct expression *, int *,
+ enum noside, int);
-static LONGEST
- init_array_element PARAMS ((value_ptr, value_ptr, struct expression *,
- int *, enum noside, LONGEST, LONGEST));
-
-#ifdef __GNUC__
-inline
-#endif
-static value_ptr
-evaluate_subexp (expect_type, exp, pos, noside)
- struct type *expect_type;
- register struct expression *exp;
- register int *pos;
- enum noside noside;
+static LONGEST init_array_element (struct value *, struct value *,
+ struct expression *, int *, enum noside,
+ LONGEST, LONGEST);
+
+static struct value *
+evaluate_subexp (struct type *expect_type, register struct expression *exp,
+ register int *pos, enum noside noside)
{
return (*exp->language_defn->evaluate_exp) (expect_type, exp, pos, noside);
}
and return the result as a number. */
CORE_ADDR
-parse_and_eval_address (exp)
- char *exp;
+parse_and_eval_address (char *exp)
{
struct expression *expr = parse_expression (exp);
register CORE_ADDR addr;
register struct cleanup *old_chain =
- make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+ make_cleanup (free_current_contents, &expr);
- addr = value_as_pointer (evaluate_expression (expr));
+ addr = value_as_address (evaluate_expression (expr));
do_cleanups (old_chain);
return addr;
}
and advanced that variable across the characters parsed. */
CORE_ADDR
-parse_and_eval_address_1 (expptr)
- char **expptr;
+parse_and_eval_address_1 (char **expptr)
{
struct expression *expr = parse_exp_1 (expptr, (struct block *) 0, 0);
register CORE_ADDR addr;
register struct cleanup *old_chain =
- make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+ make_cleanup (free_current_contents, &expr);
- addr = value_as_pointer (evaluate_expression (expr));
+ addr = value_as_address (evaluate_expression (expr));
do_cleanups (old_chain);
return addr;
}
-value_ptr
-parse_and_eval (exp)
- char *exp;
+/* Like parse_and_eval_address, but treats the value of the expression
+ as an integer, not an address, returns a LONGEST, not a CORE_ADDR */
+LONGEST
+parse_and_eval_long (char *exp)
+{
+ struct expression *expr = parse_expression (exp);
+ register LONGEST retval;
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
+
+ retval = value_as_long (evaluate_expression (expr));
+ do_cleanups (old_chain);
+ return (retval);
+}
+
+struct value *
+parse_and_eval (char *exp)
{
struct expression *expr = parse_expression (exp);
- register value_ptr val;
- register struct cleanup *old_chain
- = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+ struct value *val;
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
val = evaluate_expression (expr);
do_cleanups (old_chain);
in the string EXPP as an expression, evaluate it, and return the value.
EXPP is advanced to point to the comma. */
-value_ptr
-parse_to_comma_and_eval (expp)
- char **expp;
+struct value *
+parse_to_comma_and_eval (char **expp)
{
struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1);
- register value_ptr val;
- register struct cleanup *old_chain
- = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+ struct value *val;
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
val = evaluate_expression (expr);
do_cleanups (old_chain);
See expression.h for info on the format of an expression. */
-value_ptr
-evaluate_expression (exp)
- struct expression *exp;
+struct value *
+evaluate_expression (struct expression *exp)
{
int pc = 0;
return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_NORMAL);
/* Evaluate an expression, avoiding all memory references
and getting a value whose type alone is correct. */
-value_ptr
-evaluate_type (exp)
- struct expression *exp;
+struct value *
+evaluate_type (struct expression *exp)
{
int pc = 0;
return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
returning the label. Otherwise, does nothing and returns NULL. */
static char *
-get_label (exp, pos)
- register struct expression *exp;
- int *pos;
+get_label (register struct expression *exp, int *pos)
{
if (exp->elts[*pos].opcode == OP_LABELED)
{
return NULL;
}
-/* This function evaluates tupes (in Chill) or brace-initializers
- (in C/C++) for structure types. */
+/* This function evaluates tuples (in (the deleted) Chill) or
+ brace-initializers (in C/C++) for structure types. */
-static value_ptr
-evaluate_struct_tuple (struct_val, exp, pos, noside, nargs)
- value_ptr struct_val;
- register struct expression *exp;
- register int *pos;
- enum noside noside;
- int nargs;
+static struct value *
+evaluate_struct_tuple (struct value *struct_val,
+ register struct expression *exp,
+ register int *pos, enum noside noside, int nargs)
{
struct type *struct_type = check_typedef (VALUE_TYPE (struct_val));
struct type *substruct_type = struct_type;
while (--nargs >= 0)
{
int pc = *pos;
- value_ptr val = NULL;
+ struct value *val = NULL;
int nlabels = 0;
int bitpos, bitsize;
char *addr;
return struct_val;
}
-/* Recursive helper function for setting elements of array tuples for Chill.
- 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
- ARRAY to ELEMENT.
- Returns last index value. */
+/* Recursive helper function for setting elements of array tuples for
+ (the deleted) Chill. 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 ARRAY to ELEMENT. Returns last index
+ value. */
static LONGEST
-init_array_element (array, element, exp, pos, noside, low_bound, high_bound)
- value_ptr array, element;
- register struct expression *exp;
- register int *pos;
- enum noside noside;
- LONGEST low_bound, high_bound;
+init_array_element (struct value *array, struct value *element,
+ register struct expression *exp, register int *pos,
+ enum noside noside, LONGEST low_bound, LONGEST high_bound)
{
LONGEST index;
int element_size = TYPE_LENGTH (VALUE_TYPE (element));
return index;
}
-value_ptr
-evaluate_subexp_standard (expect_type, exp, pos, noside)
- struct type *expect_type;
- register struct expression *exp;
- register int *pos;
- enum noside noside;
+struct value *
+evaluate_subexp_standard (struct type *expect_type,
+ register struct expression *exp, register int *pos,
+ enum noside noside)
{
enum exp_opcode op;
int tem, tem2, tem3;
register int pc, pc2 = 0, oldpos;
- register value_ptr arg1 = NULL, arg2 = NULL, arg3;
+ struct value *arg1 = NULL;
+ struct value *arg2 = NULL;
+ struct value *arg3;
struct type *type;
int nargs;
- value_ptr *argvec;
+ struct value **argvec;
int upper, lower, retcode;
int code;
int ix;
long mem_offset;
- struct symbol *sym;
struct type **arg_types;
int save_pos1;
(*pos) += 3;
if (noside == EVAL_SKIP)
goto nosideret;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- struct symbol *sym = exp->elts[pc + 2].symbol;
- enum lval_type lv;
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_CONST:
- case LOC_LABEL:
- case LOC_CONST_BYTES:
- lv = not_lval;
- break;
-
- case LOC_REGISTER:
- case LOC_REGPARM:
- lv = lval_register;
- break;
-
- default:
- lv = lval_memory;
- break;
- }
+ /* 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. */
- return value_zero (SYMBOL_TYPE (sym), lv);
- }
- else
return value_of_variable (exp->elts[pc + 2].symbol,
exp->elts[pc + 1].block);
case OP_REGISTER:
{
int regno = longest_to_int (exp->elts[pc + 1].longconst);
- value_ptr val = value_of_register (regno);
-
+ struct value *val = value_of_register (regno, deprecated_selected_frame);
(*pos) += 2;
if (val == NULL)
- error ("Value of register %s not available.", REGISTER_NAME (regno));
+ error ("Value of register %s not available.",
+ frame_map_regnum_to_name (regno));
else
return val;
}
if (expect_type != NULL_TYPE && noside != EVAL_SKIP
&& TYPE_CODE (type) == TYPE_CODE_STRUCT)
{
- value_ptr rec = allocate_value (expect_type);
+ struct value *rec = allocate_value (expect_type);
memset (VALUE_CONTENTS_RAW (rec), '\0', TYPE_LENGTH (type));
return evaluate_struct_tuple (rec, exp, pos, noside, nargs);
}
{
struct type *range_type = TYPE_FIELD_TYPE (type, 0);
struct type *element_type = TYPE_TARGET_TYPE (type);
- value_ptr array = allocate_value (expect_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) < 0)
memset (VALUE_CONTENTS_RAW (array), 0, TYPE_LENGTH (expect_type));
for (tem = nargs; --nargs >= 0;)
{
- value_ptr element;
+ struct value *element;
int index_pc = 0;
if (exp->elts[*pos].opcode == BINOP_RANGE)
{
if (expect_type != NULL_TYPE && noside != EVAL_SKIP
&& TYPE_CODE (type) == TYPE_CODE_SET)
{
- value_ptr set = allocate_value (expect_type);
+ struct value *set = allocate_value (expect_type);
char *valaddr = VALUE_CONTENTS_RAW (set);
struct type *element_type = TYPE_INDEX_TYPE (type);
struct type *check_type = element_type;
{
LONGEST range_low, range_high;
struct type *range_low_type, *range_high_type;
- value_ptr elem_val;
+ struct value *elem_val;
if (exp->elts[*pos].opcode == BINOP_RANGE)
{
(*pos)++;
return set;
}
- argvec = (value_ptr *) alloca (sizeof (value_ptr) * nargs);
+ argvec = (struct value **) alloca (sizeof (struct value *) * nargs);
for (tem = 0; tem < nargs; tem++)
{
/* Ensure that array expressions are coerced into pointer objects. */
case TERNOP_SLICE:
{
- value_ptr array = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ struct value *array = evaluate_subexp (NULL_TYPE, exp, pos, noside);
int lowbound
= value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
int upper
case TERNOP_SLICE_COUNT:
{
- value_ptr array = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ struct value *array = evaluate_subexp (NULL_TYPE, exp, pos, noside);
int lowbound
= value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
int length
nargs = longest_to_int (exp->elts[pc + 1].longconst);
/* Allocate arg vector, including space for the function to be
called in argvec[0] and a terminating NULL */
- argvec = (value_ptr *) alloca (sizeof (value_ptr) * (nargs + 3));
+ argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 3));
if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
{
LONGEST fnptr;
for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j)
if ((int) TYPE_FN_FIELD_VOFFSET (f, j) == fnoffset)
{
- value_ptr temp = value_ind (arg2);
+ struct value *temp = value_ind (arg2);
arg1 = value_virtual_fn_field (&temp, f, j, domain_type, 0);
arg2 = value_addr (temp);
goto got_it;
if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
{
int static_memfuncp;
- value_ptr temp = arg2;
char tstr[256];
- struct fn_field *fns_ptr;
- int num_fns;
- struct type *basetype;
- int boffset;
/* Method invocation : stuff "this" as first parameter */
- /* pai: this used to have lookup_pointer_type for some reason,
- * but temp is already a pointer to the object */
- argvec[1] = value_from_longest (VALUE_TYPE (temp),
- VALUE_ADDRESS (temp) + VALUE_OFFSET (temp));
+ argvec[1] = arg2;
/* Name of method from expression */
strcpy (tstr, &exp->elts[pc2 + 2].string);
if (overload_resolution && (exp->language_defn->la_language == language_cplus))
{
/* Language is C++, do some overload resolution before evaluation */
- value_ptr valp = NULL;
+ struct value *valp = NULL;
/* Prepare list of argument types for overload resolution */
- arg_types = (struct type **) xmalloc (nargs * (sizeof (struct type *)));
+ arg_types = (struct type **) alloca (nargs * (sizeof (struct type *)));
for (ix = 1; ix <= nargs; ix++)
arg_types[ix - 1] = VALUE_TYPE (argvec[ix]);
(void) find_overload_match (arg_types, nargs, tstr,
1 /* method */ , 0 /* strict match */ ,
- arg2 /* the object */ , NULL,
+ &arg2 /* the object */ , NULL,
&valp, NULL, &static_memfuncp);
else
/* Non-C++ case -- or no overload resolution */
{
- temp = arg2;
+ 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_OFFSET (temp)
+ + VALUE_EMBEDDED_OFFSET (temp));
argvec[1] = arg2; /* the ``this'' pointer */
}
argvec[1] = arg2;
argvec[0] = arg1;
}
- else
+ else if (op == OP_VAR_VALUE)
{
/* 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))
{
struct symbol *symp;
/* Prepare list of argument types for overload resolution */
- arg_types = (struct type **) xmalloc (nargs * (sizeof (struct type *)));
+ arg_types = (struct type **) alloca (nargs * (sizeof (struct type *)));
for (ix = 1; ix <= nargs; ix++)
arg_types[ix - 1] = VALUE_TYPE (argvec[ix]);
(void) find_overload_match (arg_types, nargs, NULL /* no need for name */ ,
0 /* not method */ , 0 /* strict match */ ,
- NULL, exp->elts[5].symbol /* the function */ ,
+ NULL, exp->elts[save_pos1+2].symbol /* the function */ ,
NULL, &symp, NULL);
/* Now fix the expression being evaluated */
- exp->elts[5].symbol = symp;
+ exp->elts[save_pos1+2].symbol = symp;
argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);
}
else
/* 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 (noside == EVAL_SKIP)
goto nosideret;
+ 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
else
error ("Expression of type other than \"Function returning ...\" used as function");
}
- if (argvec[0] == NULL)
- error ("Cannot evaluate function -- may be inlined");
return call_function_by_hand (argvec[0], nargs, argvec + 1);
/* pai: FIXME save value from call_function_by_hand, then adjust pc by adjust_fn_pc if +ve */
/* It's a function call. */
/* Allocate arg vector, including space for the function to be
called in argvec[0] and a terminating NULL */
- argvec = (value_ptr *) alloca (sizeof (value_ptr) * (nargs + 2));
+ argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 2));
argvec[0] = arg1;
tem = 1;
for (; tem <= nargs; tem++)
lval_memory);
else
{
- value_ptr temp = arg1;
+ struct value *temp = arg1;
return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
NULL, "structure");
}
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
+
+ /* JYG: if print object is on we need to replace the base type
+ 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 *real_type;
+ int full, top, using_enc;
+
+ if (objectprint && TYPE_TARGET_TYPE(type) &&
+ (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+ {
+ real_type = value_rtti_target_type (arg1, &full, &top, &using_enc);
+ if (real_type)
+ {
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ real_type = lookup_pointer_type (real_type);
+ else
+ real_type = lookup_reference_type (real_type);
+
+ arg1 = value_cast (real_type, arg1);
+ }
+ }
+ }
+
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1),
&exp->elts[pc + 2].string,
lval_memory);
else
{
- value_ptr temp = arg1;
+ struct value *temp = arg1;
return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
NULL, "structure pointer");
}
/* Now, convert these values to an address. */
arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
arg1);
- arg3 = value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
+ arg3 = value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
value_as_long (arg1) + mem_offset);
return value_ind (arg3);
bad_pointer_to_member:
}
else
{
- value_ptr retvalp = evaluate_subexp_for_address (exp, pos, noside);
+ struct value *retvalp = evaluate_subexp_for_address (exp, pos, noside);
/* If HP aCC object, use bias for pointers to members */
if (hp_som_som_object_present &&
(TYPE_CODE (VALUE_TYPE (retvalp)) == TYPE_CODE_PTR) &&
return value_zero (exp->elts[pc + 1].type, lval_memory);
else
return value_at_lazy (exp->elts[pc + 1].type,
- value_as_pointer (arg1),
+ value_as_address (arg1),
NULL);
case UNOP_PREINCREMENT:
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 (e.g. do we need a BINOP_SCOPE
- and an OP_SCOPE?); others are legitimate expressions which are
- (apparently) not fully implemented.
+ 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
NOSIDE may be EVAL_AVOID_SIDE_EFFECTS;
then only the type of the result need be correct. */
-static value_ptr
-evaluate_subexp_for_address (exp, pos, noside)
- register struct expression *exp;
- register int *pos;
- enum noside noside;
+static struct value *
+evaluate_subexp_for_address (register struct expression *exp, register int *pos,
+ enum noside noside)
{
enum exp_opcode op;
register int pc;
default_case:
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
- value_ptr x = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ struct value *x = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (VALUE_LVAL (x) == lval_memory)
return value_zero (lookup_pointer_type (VALUE_TYPE (x)),
not_lval);
*/
-value_ptr
-evaluate_subexp_with_coercion (exp, pos, noside)
- register struct expression *exp;
- register int *pos;
- enum noside noside;
+struct value *
+evaluate_subexp_with_coercion (register struct expression *exp,
+ register int *pos, enum noside noside)
{
register enum exp_opcode op;
register int pc;
- register value_ptr val;
+ struct value *val;
struct symbol *var;
pc = (*pos);
val =
locate_var_value
(var, block_innermost_frame (exp->elts[pc + 1].block));
- return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (var))),
+ return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (check_typedef (SYMBOL_TYPE (var)))),
val);
}
/* FALLTHROUGH */
and return a value for the size of that subexpression.
Advance *POS over the subexpression. */
-static value_ptr
-evaluate_subexp_for_sizeof (exp, pos)
- register struct expression *exp;
- register int *pos;
+static struct value *
+evaluate_subexp_for_sizeof (register struct expression *exp, register int *pos)
{
enum exp_opcode op;
register int pc;
struct type *type;
- value_ptr val;
+ struct value *val;
pc = (*pos);
op = exp->elts[pc].opcode;
/* Parse a type expression in the string [P..P+LENGTH). */
struct type *
-parse_and_eval_type (p, length)
- char *p;
- int length;
+parse_and_eval_type (char *p, int length)
{
char *tmp = (char *) alloca (length + 4);
struct expression *expr;
}
int
-calc_f77_array_dims (array_type)
- struct type *array_type;
+calc_f77_array_dims (struct type *array_type)
{
int ndimen = 1;
struct type *tmp_type;