/* Evaluate expressions for GDB.
- Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 97, 1998
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000
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 value_ptr evaluate_subexp_for_sizeof (struct expression *, int *);
-static value_ptr evaluate_subexp_for_address PARAMS ((struct expression *,
- int *, enum noside));
+static value_ptr evaluate_subexp_for_address (struct expression *,
+ int *, enum noside);
-static value_ptr evaluate_subexp PARAMS ((struct type *, struct expression *,
- int *, enum noside));
+static value_ptr 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));
+evaluate_struct_tuple (value_ptr, struct expression *, int *,
+ enum noside, int);
static LONGEST
- init_array_element PARAMS ((value_ptr, value_ptr, struct expression *,
- int *, enum noside, LONGEST, LONGEST));
+init_array_element (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;
+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));
do_cleanups (old_chain);
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));
do_cleanups (old_chain);
return addr;
}
+/* 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);
+}
+
value_ptr
-parse_and_eval (exp)
- char *exp;
+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);
+ = make_cleanup (free_current_contents, &expr);
val = evaluate_expression (expr);
do_cleanups (old_chain);
EXPP is advanced to point to the comma. */
value_ptr
-parse_to_comma_and_eval (expp)
- char **expp;
+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);
+ = 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;
+evaluate_expression (struct expression *exp)
{
int pc = 0;
return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_NORMAL);
and getting a value whose type alone is correct. */
value_ptr
-evaluate_type (exp)
- struct expression *exp;
+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
+/* This function evaluates tuples (in 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;
+evaluate_struct_tuple (value_ptr 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;
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 (value_ptr array, value_ptr 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));
}
value_ptr
-evaluate_subexp_standard (expect_type, exp, pos, noside)
- struct type *expect_type;
- register struct expression *exp;
- register int *pos;
- enum noside noside;
+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;
(*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);
/* 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]
+ = value_from_pointer (VALUE_TYPE (temp),
+ VALUE_ADDRESS (temp) + VALUE_OFFSET (temp));
/* Name of method from expression */
strcpy (tstr, &exp->elts[pc2 + 2].string);
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))
{
(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:
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,
/* 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:
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;
+evaluate_subexp_for_address (register struct expression *exp, register int *pos,
+ enum noside noside)
{
enum exp_opcode op;
register int pc;
*/
value_ptr
-evaluate_subexp_with_coercion (exp, pos, noside)
- register struct expression *exp;
- register int *pos;
- enum noside noside;
+evaluate_subexp_with_coercion (register struct expression *exp,
+ register int *pos, enum noside noside)
{
register enum exp_opcode op;
register int pc;
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 */
Advance *POS over the subexpression. */
static value_ptr
-evaluate_subexp_for_sizeof (exp, pos)
- register struct expression *exp;
- register int *pos;
+evaluate_subexp_for_sizeof (register struct expression *exp, register int *pos)
{
enum exp_opcode op;
register int pc;
/* 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;