/* 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"
+#include "infcall.h"
+#include "objc-lang.h"
+#include "block.h"
+#include "parser-defs.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, struct expression *exp,
+ int *pos, enum noside noside)
{
- return (*exp->language_defn->evaluate_exp) (expect_type, exp, pos, noside);
+ return (*exp->language_defn->la_exp_desc->evaluate_exp)
+ (expect_type, exp, pos, noside);
}
\f
/* Parse the string EXP as a C expression, evaluate it,
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);
+ CORE_ADDR addr;
+ struct cleanup *old_chain =
+ 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);
+ CORE_ADDR addr;
+ struct cleanup *old_chain =
+ 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);
+ LONGEST retval;
+ 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;
+ 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;
+ 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 (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,
+ struct expression *exp,
+ 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,
+ struct expression *exp, 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,
+ struct expression *exp, 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;
+ int pc, pc2 = 0, oldpos;
+ 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;
case OP_SCOPE:
tem = longest_to_int (exp->elts[pc + 2].longconst);
(*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1);
- arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
- 0,
- exp->elts[pc + 1].type,
- &exp->elts[pc + 3].string,
- NULL_TYPE);
+ arg1 = value_aggregate_elt (exp->elts[pc + 1].type,
+ &exp->elts[pc + 3].string,
+ noside);
if (arg1 == NULL)
error ("There is no field named %s", &exp->elts[pc + 3].string);
return arg1;
(*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, get_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 (get_selected_frame (), regno));
else
return val;
}
goto nosideret;
return value_string (&exp->elts[pc + 2].string, tem);
+ 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)
+ {
+ goto nosideret;
+ }
+ return (struct value *) value_nsstring (&exp->elts[pc + 2].string, tem + 1);
+
case OP_BITSTRING:
tem = longest_to_int (exp->elts[pc + 1].longconst);
(*pos)
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
return arg2;
}
+ case OP_OBJC_SELECTOR:
+ { /* Objective C @selector operator. */
+ char *sel = &exp->elts[pc + 2].string;
+ int len = longest_to_int (exp->elts[pc + 1].longconst);
+
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (len + 1);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ if (sel[len] != 0)
+ sel[len] = 0; /* Make sure it's terminated. */
+ return value_from_longest (lookup_pointer_type (builtin_type_void),
+ lookup_child_selector (sel));
+ }
+
+ case OP_OBJC_MSGCALL:
+ { /* Objective C message (method) call. */
+
+ static unsigned long responds_selector = 0;
+ static unsigned long method_selector = 0;
+
+ unsigned long selector = 0;
+
+ int using_gcc = 0;
+ int struct_return = 0;
+ int sub_no_side = 0;
+
+ static struct value *msg_send = NULL;
+ static struct value *msg_send_stret = NULL;
+ static int gnu_runtime = 0;
+
+ struct value *target = NULL;
+ struct value *method = NULL;
+ struct value *called_method = NULL;
+
+ struct type *selector_type = NULL;
+
+ struct value *ret = NULL;
+ CORE_ADDR addr = 0;
+
+ selector = exp->elts[pc + 1].longconst;
+ nargs = exp->elts[pc + 2].longconst;
+ argvec = (struct value **) alloca (sizeof (struct value *)
+ * (nargs + 5));
+
+ (*pos) += 3;
+
+ selector_type = lookup_pointer_type (builtin_type_void);
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ sub_no_side = EVAL_NORMAL;
+ else
+ sub_no_side = noside;
+
+ target = evaluate_subexp (selector_type, exp, pos, sub_no_side);
+
+ if (value_as_long (target) == 0)
+ return value_from_longest (builtin_type_long, 0);
+
+ if (lookup_minimal_symbol ("objc_msg_lookup", 0, 0))
+ gnu_runtime = 1;
+
+ /* Find the method dispatch (Apple runtime) or method lookup
+ (GNU runtime) function for Objective-C. These will be used
+ to lookup the symbol information for the method. If we
+ can't find any symbol information, then we'll use these to
+ call the method, otherwise we can call the method
+ directly. The msg_send_stret function is used in the special
+ case of a method that returns a structure (Apple runtime
+ only). */
+ if (gnu_runtime)
+ {
+ msg_send = find_function_in_inferior ("objc_msg_lookup");
+ msg_send_stret = find_function_in_inferior ("objc_msg_lookup");
+ }
+ else
+ {
+ msg_send = find_function_in_inferior ("objc_msgSend");
+ /* Special dispatcher for methods returning structs */
+ msg_send_stret = find_function_in_inferior ("objc_msgSend_stret");
+ }
+
+ /* Verify the target object responds to this method. The
+ standard top-level 'Object' class uses a different name for
+ the verification method than the non-standard, but more
+ often used, 'NSObject' class. Make sure we check for both. */
+
+ responds_selector = lookup_child_selector ("respondsToSelector:");
+ if (responds_selector == 0)
+ responds_selector = lookup_child_selector ("respondsTo:");
+
+ if (responds_selector == 0)
+ error ("no 'respondsTo:' or 'respondsToSelector:' method");
+
+ method_selector = lookup_child_selector ("methodForSelector:");
+ if (method_selector == 0)
+ method_selector = lookup_child_selector ("methodFor:");
+
+ if (method_selector == 0)
+ error ("no 'methodFor:' or 'methodForSelector:' method");
+
+ /* Call the verification method, to make sure that the target
+ class implements the desired method. */
+
+ argvec[0] = msg_send;
+ argvec[1] = target;
+ argvec[2] = value_from_longest (builtin_type_long, responds_selector);
+ argvec[3] = value_from_longest (builtin_type_long, selector);
+ argvec[4] = 0;
+
+ ret = call_function_by_hand (argvec[0], 3, argvec + 1);
+ if (gnu_runtime)
+ {
+ /* Function objc_msg_lookup returns a pointer. */
+ argvec[0] = ret;
+ ret = call_function_by_hand (argvec[0], 3, argvec + 1);
+ }
+ if (value_as_long (ret) == 0)
+ error ("Target does not respond to this message selector.");
+
+ /* Call "methodForSelector:" method, to get the address of a
+ function method that implements this selector for this
+ class. If we can find a symbol at that address, then we
+ know the return type, parameter types etc. (that's a good
+ thing). */
+
+ argvec[0] = msg_send;
+ argvec[1] = target;
+ argvec[2] = value_from_longest (builtin_type_long, method_selector);
+ argvec[3] = value_from_longest (builtin_type_long, selector);
+ argvec[4] = 0;
+
+ ret = call_function_by_hand (argvec[0], 3, argvec + 1);
+ if (gnu_runtime)
+ {
+ argvec[0] = ret;
+ ret = call_function_by_hand (argvec[0], 3, argvec + 1);
+ }
+
+ /* ret should now be the selector. */
+
+ addr = value_as_long (ret);
+ if (addr)
+ {
+ struct symbol *sym = NULL;
+ /* Is it a high_level symbol? */
+
+ sym = find_pc_function (addr);
+ if (sym != NULL)
+ method = value_of_variable (sym, 0);
+ }
+
+ /* If we found a method with symbol information, check to see
+ if it returns a struct. Otherwise assume it doesn't. */
+
+ if (method)
+ {
+ struct block *b;
+ CORE_ADDR funaddr;
+ struct type *value_type;
+
+ funaddr = find_function_addr (method, &value_type);
+
+ b = block_for_pc (funaddr);
+
+ /* If compiled without -g, assume GCC 2. */
+ using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
+
+ CHECK_TYPEDEF (value_type);
+
+ if ((value_type == NULL)
+ || (TYPE_CODE(value_type) == TYPE_CODE_ERROR))
+ {
+ if (expect_type != NULL)
+ value_type = expect_type;
+ }
+
+ struct_return = using_struct_return (value_type, using_gcc);
+ }
+ else if (expect_type != NULL)
+ {
+ struct_return = using_struct_return (check_typedef (expect_type), using_gcc);
+ }
+
+ /* Found a function symbol. Now we will substitute its
+ value in place of the message dispatcher (obj_msgSend),
+ so that we call the method directly instead of thru
+ the dispatcher. The main reason for doing this is that
+ we can now evaluate the return value and parameter values
+ according to their known data types, in case we need to
+ do things like promotion, dereferencing, special handling
+ of structs and doubles, etc.
+
+ We want to use the type signature of 'method', but still
+ jump to objc_msgSend() or objc_msgSend_stret() to better
+ mimic the behavior of the runtime. */
+
+ if (method)
+ {
+ if (TYPE_CODE (VALUE_TYPE (method)) != TYPE_CODE_FUNC)
+ error ("method address has symbol information with non-function type; skipping");
+ if (struct_return)
+ VALUE_ADDRESS (method) = value_as_address (msg_send_stret);
+ else
+ VALUE_ADDRESS (method) = value_as_address (msg_send);
+ called_method = method;
+ }
+ else
+ {
+ if (struct_return)
+ called_method = msg_send_stret;
+ else
+ called_method = msg_send;
+ }
+
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ 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. This is here
+ because people often want to call, eg, strcmp, which
+ gdb doesn't know is a function. If gdb isn't asked for
+ it's opinion (ie. through "whatis"), it won't offer
+ it. */
+
+ struct type *type = VALUE_TYPE (called_method);
+ if (type && TYPE_CODE (type) == TYPE_CODE_PTR)
+ type = TYPE_TARGET_TYPE (type);
+ type = TYPE_TARGET_TYPE (type);
+
+ if (type)
+ {
+ if ((TYPE_CODE (type) == TYPE_CODE_ERROR) && expect_type)
+ return allocate_value (expect_type);
+ else
+ return allocate_value (type);
+ }
+ else
+ error ("Expression of type other than \"method returning ...\" used as a method");
+ }
+
+ /* Now depending on whether we found a symbol for the method,
+ we will either call the runtime dispatcher or the method
+ directly. */
+
+ argvec[0] = called_method;
+ argvec[1] = target;
+ argvec[2] = value_from_longest (builtin_type_long, selector);
+ /* User-supplied arguments. */
+ for (tem = 0; tem < nargs; tem++)
+ argvec[tem + 3] = evaluate_subexp_with_coercion (exp, pos, noside);
+ argvec[tem + 3] = 0;
+
+ if (gnu_runtime && (method != NULL))
+ {
+ ret = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
+ /* Function objc_msg_lookup returns a pointer. */
+ argvec[0] = ret;
+ ret = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
+ }
+ else
+ ret = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
+
+ return ret;
+ }
+ 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] 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:
(*pos) += 1;
return value_of_this (1);
+ case OP_OBJC_SELF:
+ (*pos) += 1;
+ return value_of_local ("self", 1);
+
case OP_TYPE:
error ("Attempt to use a type name as an expression");
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 (struct expression *exp, int *pos,
+ enum noside noside)
{
enum exp_opcode op;
- register int pc;
+ int pc;
struct symbol *var;
pc = (*pos);
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 (struct expression *exp,
+ int *pos, enum noside noside)
{
- register enum exp_opcode op;
- register int pc;
- register value_ptr val;
+ enum exp_opcode op;
+ int pc;
+ 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 (struct expression *exp, int *pos)
{
enum exp_opcode op;
- register int pc;
+ 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;