/* Evaluate expressions for GDB.
- Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008,
- 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1986-2003, 2005-2012 Free Software Foundation, Inc.
This file is part of GDB.
#include "expression.h"
#include "target.h"
#include "frame.h"
-#include "language.h" /* For CAST_IS_CONVERSION */
-#include "f-lang.h" /* for array bound stuff */
+#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 "gdb_obstack.h"
#include "objfiles.h"
#include "python/python.h"
-#include "wrapper.h"
#include "gdb_assert.h"
/* This is defined in valops.c */
extern int overload_resolution;
-/* Prototypes for local functions. */
+/* Prototypes for local functions. */
static struct value *evaluate_subexp_for_sizeof (struct expression *, int *);
return addr;
}
-/* Like parse_and_eval_address but takes a pointer to a char * variable
- and advanced that variable across the characters parsed. */
-
-CORE_ADDR
-parse_and_eval_address_1 (char **expptr)
-{
- struct expression *expr = parse_exp_1 (expptr, (struct block *) 0, 0);
- CORE_ADDR addr;
- struct cleanup *old_chain =
- make_cleanup (free_current_contents, &expr);
-
- addr = value_as_address (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 */
+ as an integer, not an address, returns a LONGEST, not a CORE_ADDR. */
LONGEST
parse_and_eval_long (char *exp)
{
/* Make sure it's not lazy, so that after the target stops again we
have a non-lazy previous value to compare with. */
- if (result != NULL
- && (!value_lazy (result) || gdb_value_fetch_lazy (result)))
- *valp = result;
+ if (result != NULL)
+ {
+ if (!value_lazy (result))
+ *valp = result;
+ else
+ {
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ value_fetch_lazy (result);
+ *valp = result;
+ }
+ }
+ }
if (val_chain)
{
}
/* If the next expression is an OP_LABELED, skips past it,
- returning the label. Otherwise, does nothing and returns NULL. */
+ returning the label. Otherwise, does nothing and returns NULL. */
static char *
get_label (struct expression *exp, int *pos)
int bitpos, bitsize;
bfd_byte *addr;
- /* Skip past the labels, and count them. */
+ /* Skip past the labels, and count them. */
while (get_label (exp, pos) != NULL)
nlabels++;
}
else
{
- /* Unlabelled tuple element - go to next field. */
+ /* Unlabelled tuple element - go to next field. */
if (variantno >= 0)
{
subfieldno++;
The value fieldno is the index of the top-level (normal or
anonymous union) field in struct_field, while the value
subfieldno is the index of the actual real (named inner) field
- in substruct_type. */
+ in substruct_type. */
field_type = TYPE_FIELD_TYPE (substruct_type, subfieldno);
if (val == 0)
val = evaluate_subexp (field_type, exp, pos, noside);
- /* Now actually set the field in struct_val. */
+ /* Now actually set the field in struct_val. */
- /* Assign val to field fieldno. */
+ /* Assign val to field fieldno. */
if (value_type (val) != field_type)
val = value_cast (field_type, val);
case language_cplus:
case language_asm:
case language_objc:
+ case language_opencl:
/* No promotion required. */
break;
: builtin->builtin_long_long);
}
break;
-
+ case language_opencl:
+ if (result_len <= TYPE_LENGTH (lookup_signed_typename
+ (language, gdbarch, "int")))
+ {
+ promoted_type =
+ (unsigned_operation
+ ? lookup_unsigned_typename (language, gdbarch, "int")
+ : lookup_signed_typename (language, gdbarch, "int"));
+ }
+ else if (result_len <= TYPE_LENGTH (lookup_signed_typename
+ (language, gdbarch, "long")))
+ {
+ promoted_type =
+ (unsigned_operation
+ ? lookup_unsigned_typename (language, gdbarch, "long")
+ : lookup_signed_typename (language, gdbarch,"long"));
+ }
+ break;
default:
/* For other languages the result type is unchanged from gdb
version 6.7 for backward compatibility.
return 1;
case TYPE_CODE_ARRAY:
- return lang->c_style_arrays;
+ return TYPE_VECTOR (type) ? 0 : lang->c_style_arrays;
default:
return 0;
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. */
+ or reference to a base class and print object is on. */
{
volatile struct gdb_exception except;
if (except.reason < 0)
{
if (noside == EVAL_AVOID_SIDE_EFFECTS)
- ret = value_zero (SYMBOL_TYPE (exp->elts[pc + 2].symbol), not_lval);
+ ret = value_zero (SYMBOL_TYPE (exp->elts[pc + 2].symbol),
+ not_lval);
else
throw_exception (except);
}
return ret;
}
+ case OP_VAR_ENTRY_VALUE:
+ (*pos) += 2;
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+
+ {
+ struct symbol *sym = exp->elts[pc + 1].symbol;
+ struct frame_info *frame;
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (SYMBOL_TYPE (sym), not_lval);
+
+ if (SYMBOL_CLASS (sym) != LOC_COMPUTED
+ || SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry == NULL)
+ error (_("Symbol \"%s\" does not have any specific entry value"),
+ SYMBOL_PRINT_NAME (sym));
+
+ frame = get_selected_frame (NULL);
+ return SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry (sym, frame);
+ }
+
case OP_LAST:
(*pos) += 2;
return
type = language_string_char_type (exp->language_defn, exp->gdbarch);
return value_string (&exp->elts[pc + 2].string, tem, type);
- case OP_OBJC_NSSTRING: /* Objective C Foundation Class NSString constant. */
+ 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)
else
{
if (index > high_bound)
- /* to avoid memory corruption */
+ /* To avoid memory corruption. */
error (_("Too many array elements"));
memcpy (value_contents_raw (array)
+ (index - low_bound) * element_size,
struct type *check_type = element_type;
LONGEST low_bound, high_bound;
- /* get targettype of elementtype */
+ /* Get targettype of elementtype. */
while (TYPE_CODE (check_type) == TYPE_CODE_RANGE
|| TYPE_CODE (check_type) == TYPE_CODE_TYPEDEF)
check_type = TYPE_TARGET_TYPE (check_type);
range_low_type = range_high_type = value_type (elem_val);
range_low = range_high = value_as_long (elem_val);
}
- /* check types of elements to avoid mixture of elements from
+ /* Check types of elements to avoid mixture of elements from
different types. Also check if type of element is "compatible"
- with element type of powerset */
+ with element type of powerset. */
if (TYPE_CODE (range_low_type) == TYPE_CODE_RANGE)
range_low_type = TYPE_TARGET_TYPE (range_low_type);
if (TYPE_CODE (range_high_type) == TYPE_CODE_RANGE)
if ((TYPE_CODE (range_low_type) != TYPE_CODE (range_high_type))
|| (TYPE_CODE (range_low_type) == TYPE_CODE_ENUM
&& (range_low_type != range_high_type)))
- /* different element modes */
+ /* different element modes. */
error (_("POWERSET tuple elements of different mode"));
if ((TYPE_CODE (check_type) != TYPE_CODE (range_low_type))
|| (TYPE_CODE (check_type) == TYPE_CODE_ENUM
argvec = (struct value **) alloca (sizeof (struct value *) * nargs);
for (tem = 0; tem < nargs; tem++)
{
- /* Ensure that array expressions are coerced into pointer objects. */
+ /* Ensure that array expressions are coerced into pointer
+ objects. */
argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
}
if (noside == EVAL_SKIP)
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
+ 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)
else
{
msg_send = find_function_in_inferior ("objc_msgSend", NULL);
- /* Special dispatcher for methods returning structs */
+ /* Special dispatcher for methods returning structs. */
msg_send_stret
= find_function_in_inferior ("objc_msgSend_stret", NULL);
}
- /* Verify the target object responds to this method. The
+ /* 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. */
+ often used, 'NSObject' class. Make sure we check for both. */
responds_selector
= lookup_child_selector (exp->gdbarch, "respondsToSelector:");
error (_("no 'methodFor:' or 'methodForSelector:' method"));
/* Call the verification method, to make sure that the target
- class implements the desired method. */
+ class implements the desired method. */
argvec[0] = msg_send;
argvec[1] = target;
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). */
+ thing). */
argvec[0] = msg_send;
argvec[1] = target;
if (method)
{
- struct block *b;
CORE_ADDR funaddr;
struct type *val_type;
funaddr = find_function_addr (method, &val_type);
- b = block_for_pc (funaddr);
+ block_for_pc (funaddr);
CHECK_TYPEDEF (val_type);
}
struct_return = using_struct_return (exp->gdbarch,
- value_type (method), val_type);
+ value_type (method),
+ val_type);
}
else if (expect_type != NULL)
{
if (method)
{
if (TYPE_CODE (value_type (method)) != TYPE_CODE_FUNC)
- error (_("method address has symbol information with non-function type; skipping"));
-
- /* Create a function pointer of the appropriate type, and replace
- its value with the value of msg_send or msg_send_stret. We must
- use a pointer here, as msg_send and msg_send_stret are of pointer
- type, and the representation may be different on systems that use
+ error (_("method address has symbol information "
+ "with non-function type; skipping"));
+
+ /* Create a function pointer of the appropriate type, and
+ replace its value with the value of msg_send or
+ msg_send_stret. We must use a pointer here, as
+ msg_send and msg_send_stret are of pointer type, and
+ the representation may be different on systems that use
function descriptors. */
if (struct_return)
called_method
{
/* 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
+ 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. */
+ it. */
struct type *type = value_type (called_method);
return allocate_value (type);
}
else
- error (_("Expression of type other than \"method returning ...\" used as a method"));
+ error (_("Expression of type other than "
+ "\"method returning ...\" used as a method"));
}
/* Now depending on whether we found a symbol for the method,
/* 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], nargs + 2, argvec + 1);
+ argvec[0]
+ = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
}
ret = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
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 = (struct value **) alloca (sizeof (struct value *) * (nargs + 3));
+ called in argvec[0] and a terminating NULL. */
+ argvec = (struct value **)
+ alloca (sizeof (struct value *) * (nargs + 3));
if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
{
nargs++;
- /* First, evaluate the structure into arg2 */
+ /* First, evaluate the structure into arg2. */
pc2 = (*pos)++;
if (noside == EVAL_SKIP)
else
arg1 = cplus_method_ptr_to_value (&arg2, arg1);
- /* Now, say which argument to start evaluating from */
+ /* Now, say which argument to start evaluating from. */
tem = 2;
}
else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
{
- /* Hair for method invocations */
+ /* Hair for method invocations. */
int tem2;
nargs++;
- /* First, evaluate the structure into arg2 */
+ /* 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);
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))
+ {
+ volatile struct gdb_exception except;
+ struct value *value = NULL;
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ value = value_x_unop (arg2, op, noside);
+ }
+
+ if (except.reason < 0)
+ {
+ if (except.error == NOT_FOUND_ERROR)
+ break;
+ else
+ throw_exception (except);
+ }
+ arg2 = value;
+ }
}
- /* Now, say which argument to start evaluating from */
+ /* Now, say which argument to start evaluating from. */
tem = 2;
}
else if (op == OP_SCOPE
}
else
{
- /* Non-method function call */
+ /* Non-method function call. */
save_pos1 = *pos;
tem = 1;
{
for (; tem <= nargs && tem <= TYPE_NFIELDS (type); tem++)
{
- argvec[tem] = evaluate_subexp (TYPE_FIELD_TYPE (type, tem - 1),
+ argvec[tem] = evaluate_subexp (TYPE_FIELD_TYPE (type,
+ tem - 1),
exp, pos, noside);
}
}
}
}
- /* Evaluate arguments */
+ /* Evaluate arguments. */
for (; tem <= nargs; tem++)
{
- /* Ensure that array expressions are coerced into pointer objects. */
+ /* Ensure that array expressions are coerced into pointer
+ objects. */
argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
}
- /* signal end of arglist */
+ /* Signal end of arglist. */
argvec[tem] = 0;
if (op == OP_ADL_FUNC)
{
func_name = (char *) alloca (name_len + 1);
strcpy (func_name, &exp->elts[string_pc + 1].string);
- /* Prepare list of argument types for overload resolution */
- arg_types = (struct type **) alloca (nargs * (sizeof (struct type *)));
- for (ix = 1; ix <= nargs; ix++)
- arg_types[ix - 1] = value_type (argvec[ix]);
-
- find_overload_match (arg_types, nargs, func_name,
- NON_METHOD /* not method */ , 0 /* strict match */ ,
- NULL, NULL /* pass NULL symbol since symbol is unknown */ ,
+ find_overload_match (&argvec[1], nargs, func_name,
+ NON_METHOD, /* not method */
+ 0, /* strict match */
+ NULL, NULL, /* pass NULL symbol since
+ symbol is unknown */
NULL, &symp, NULL, 0);
/* Now fix the expression being evaluated. */
int static_memfuncp;
char *tstr;
- /* Method invocation : stuff "this" as first parameter */
+ /* Method invocation : stuff "this" as first parameter. */
argvec[1] = arg2;
if (op != OP_SCOPE)
{
- /* Name of method from expression */
+ /* 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))
+ if (overload_resolution && (exp->language_defn->la_language
+ == language_cplus))
{
- /* Language is C++, do some overload resolution before evaluation */
+ /* Language is C++, do some overload resolution before
+ evaluation. */
struct value *valp = NULL;
- /* Prepare list of argument types for overload resolution */
- 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,
- METHOD /* method */ , 0 /* strict match */ ,
- &arg2 /* the object */ , NULL,
- &valp, NULL, &static_memfuncp, 0);
+ (void) find_overload_match (&argvec[1], nargs, tstr,
+ METHOD, /* method */
+ 0, /* strict match */
+ &arg2, /* the object */
+ NULL, &valp, NULL,
+ &static_memfuncp, 0);
if (op == OP_SCOPE && !static_memfuncp)
{
function_name);
}
argvec[1] = arg2; /* the ``this'' pointer */
- argvec[0] = valp; /* use the method found after overload resolution */
+ argvec[0] = valp; /* Use the method found after overload
+ resolution. */
}
else
- /* Non-C++ case -- or no overload resolution */
+ /* Non-C++ case -- or no overload resolution. */
{
struct value *temp = arg2;
/* 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));
+ arg2
+ = value_from_longest (lookup_pointer_type(value_type (temp)),
+ value_address (temp)
+ + value_embedded_offset (temp));
argvec[1] = arg2; /* the ``this'' pointer */
}
}
else if (op == OP_VAR_VALUE || (op == OP_SCOPE && function != NULL))
{
- /* Non-member function being called */
+ /* 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 */
+ are expected here. */
- if (overload_resolution && (exp->language_defn->la_language == language_cplus))
+ if (overload_resolution && (exp->language_defn->la_language
+ == language_cplus))
{
- /* Language is C++, do some overload resolution before evaluation */
+ /* Language is C++, do some overload resolution before
+ evaluation. */
struct symbol *symp;
int no_adl = 0;
if (op == OP_VAR_VALUE)
function = exp->elts[save_pos1+2].symbol;
- /* Prepare list of argument types for overload resolution */
- 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 */ ,
- NON_METHOD /* not method */ , 0 /* strict match */ ,
- NULL, function /* the function */ ,
+ (void) find_overload_match (&argvec[1], nargs,
+ NULL, /* no need for name */
+ NON_METHOD, /* not method */
+ 0, /* strict match */
+ NULL, function, /* the function */
NULL, &symp, NULL, no_adl);
if (op == OP_VAR_VALUE)
{
- /* Now fix the expression being evaluated */
+ /* Now fix the expression being evaluated. */
exp->elts[save_pos1+2].symbol = symp;
argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1,
noside);
}
else
{
- /* Not C++, or no overload resolution allowed */
- /* nothing to be done; argvec already correctly set up */
+ /* 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 */
+ /* It is probably a C-style function. */
+ /* Nothing to be done; argvec already correctly set up. */
}
do_call_it:
{
/* 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
+ 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. */
+ it won't offer it. */
struct type *ftype = value_type (argvec[0]);
return value_zero (builtin_type (exp->gdbarch)->builtin_int,
not_lval);
}
+ else if (TYPE_GNU_IFUNC (ftype))
+ return allocate_value (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype)));
else if (TYPE_TARGET_TYPE (ftype))
return allocate_value (TYPE_TARGET_TYPE (ftype));
else
- error (_("Expression of type other than \"Function returning ...\" used as function"));
+ error (_("Expression of type other than "
+ "\"Function returning ...\" used as function"));
}
if (TYPE_CODE (value_type (argvec[0])) == TYPE_CODE_INTERNAL_FUNCTION)
return call_internal_function (exp->gdbarch, exp->language_defn,
argvec[0], nargs, argvec + 1);
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 */
+ /* pai: FIXME save value from call_function_by_hand, then adjust
+ pc by adjust_fn_pc if +ve. */
case OP_F77_UNDETERMINED_ARGLIST:
array subscript operations cannot be disambiguated
at parse time. We have made all array subscript operations,
substring operations as well as function calls come here
- and we now have to discover what the heck this thing actually was.
- If it is a function, we process just as if we got an OP_FUNCALL. */
+ and we now have to discover what the heck this thing actually was.
+ If it is a function, we process just as if we got an OP_FUNCALL. */
nargs = longest_to_int (exp->elts[pc + 1].longconst);
(*pos) += 2;
case TYPE_CODE_PTR:
case TYPE_CODE_FUNC:
- /* It's a function call. */
+ /* It's a function call. */
/* Allocate arg vector, including space for the function to be
- called in argvec[0] and a terminating NULL */
- argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 2));
+ called in argvec[0] and a terminating NULL. */
+ argvec = (struct value **)
+ alloca (sizeof (struct value *) * (nargs + 2));
argvec[0] = arg1;
tem = 1;
for (; tem <= nargs; tem++)
case OP_COMPLEX:
/* We have a complex number, There should be 2 floating
- point numbers that compose it */
+ point numbers that compose it. */
(*pos) += 2;
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
+ /* Check to see if operator '->' has been overloaded. If so replace
+ arg1 with the value returned by evaluating operator->(). */
+ while (unop_user_defined_p (op, arg1))
+ {
+ volatile struct gdb_exception except;
+ struct value *value = NULL;
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ value = value_x_unop (arg1, op, noside);
+ }
+
+ if (except.reason < 0)
+ {
+ if (except.error == NOT_FOUND_ERROR)
+ break;
+ else
+ throw_exception (except);
+ }
+ arg1 = value;
+ }
+
/* 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. */
+ lookup of member / method only available in the rtti type. */
{
struct type *type = value_type (arg1);
struct type *real_type;
return value_ind (arg3);
default:
- error (_("non-pointer-to-member value used in pointer-to-member construct"));
+ error (_("non-pointer-to-member value used "
+ "in pointer-to-member construct"));
}
case TYPE_INSTANCE:
{
struct value *v_one, *retval;
- v_one = value_one (value_type (arg2), not_lval);
+ v_one = value_one (value_type (arg2));
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &v_one);
retval = value_binop (arg1, v_one, op);
return retval;
}
case BINOP_RANGE:
- arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
error (_("':' operator used in invalid context"));
{
/* If the user attempts to subscript something that is not an
array or pointer type (like a plain int variable for example),
- then report this as an error. */
+ then report this as an error. */
arg1 = coerce_ref (arg1);
type = check_typedef (value_type (arg1));
while (nargs-- > 0)
{
arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
- /* FIXME: EVAL_SKIP handling may not be correct. */
+ /* FIXME: EVAL_SKIP handling may not be correct. */
if (noside == EVAL_SKIP)
{
if (nargs > 0)
goto nosideret;
}
}
- /* FIXME: EVAL_AVOID_SIDE_EFFECTS handling may not be correct. */
+ /* FIXME: EVAL_AVOID_SIDE_EFFECTS handling may not be correct. */
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
/* If the user attempts to subscript something that has no target
type (like a plain int variable for example), then report this
- as an error. */
+ as an error. */
type = TYPE_TARGET_TYPE (check_typedef (value_type (arg1)));
if (type != NULL)
multi_f77_subscript:
{
- int subscript_array[MAX_FORTRAN_DIMS];
- int array_size_array[MAX_FORTRAN_DIMS];
+ LONGEST subscript_array[MAX_FORTRAN_DIMS];
int ndimensions = 1, i;
- struct type *tmp_type;
- int offset_item; /* The array offset where the item lives */
+ struct value *array = arg1;
if (nargs > MAX_FORTRAN_DIMS)
error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
- tmp_type = check_typedef (value_type (arg1));
ndimensions = calc_f77_array_dims (type);
if (nargs != ndimensions)
gdb_assert (nargs > 0);
/* Now that we know we have a legal array subscript expression
- let us actually find out where this element exists in the array. */
+ let us actually find out where this element exists in the array. */
- offset_item = 0;
- /* Take array indices left to right */
+ /* Take array indices left to right. */
for (i = 0; i < nargs; i++)
{
- /* Evaluate each subscript, It must be a legal integer in F77 */
+ /* Evaluate each subscript; it must be a legal integer in F77. */
arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
- /* Fill in the subscript and array size arrays */
+ /* Fill in the subscript array. */
subscript_array[i] = value_as_long (arg2);
}
- /* Internal type of array is arranged right to left */
- for (i = 0; i < nargs; i++)
+ /* Internal type of array is arranged right to left. */
+ for (i = nargs; i > 0; i--)
{
- upper = f77_get_upperbound (tmp_type);
- lower = f77_get_lowerbound (tmp_type);
-
- array_size_array[nargs - i - 1] = upper - lower + 1;
+ struct type *array_type = check_typedef (value_type (array));
+ LONGEST index = subscript_array[i - 1];
- /* Zero-normalize subscripts so that offsetting will work. */
-
- subscript_array[nargs - i - 1] -= lower;
-
- /* If we are at the bottom of a multidimensional
- array type then keep a ptr to the last ARRAY
- type around for use when calling value_subscript()
- below. This is done because we pretend to value_subscript
- that we actually have a one-dimensional array
- of base element type that we apply a simple
- offset to. */
-
- if (i < nargs - 1)
- tmp_type = check_typedef (TYPE_TARGET_TYPE (tmp_type));
+ lower = f77_get_lowerbound (array_type);
+ array = value_subscripted_rvalue (array, index, lower);
}
- /* Now let us calculate the offset for this item */
-
- offset_item = subscript_array[ndimensions - 1];
-
- for (i = ndimensions - 1; i > 0; --i)
- offset_item =
- array_size_array[i - 1] * offset_item + subscript_array[i - 1];
-
- /* Let us now play a dirty trick: we will take arg1
- which is a value node pointing to the topmost level
- of the multidimensional array-set and pretend
- that it is actually a array of the final element
- type, this will ensure that value_subscript()
- returns the correct type value */
-
- deprecated_set_value_type (arg1, tmp_type);
- return value_subscripted_rvalue (arg1, offset_item, 0);
+ return array;
}
case BINOP_LOGICAL_AND:
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
{
- arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
goto nosideret;
}
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
{
- arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ evaluate_subexp (NULL_TYPE, exp, pos, noside);
goto nosideret;
}
type = check_typedef (value_type (arg1));
if (TYPE_CODE (type) == TYPE_CODE_METHODPTR
|| TYPE_CODE (type) == TYPE_CODE_MEMBERPTR)
- error (_("Attempt to dereference pointer to member without an object"));
+ error (_("Attempt to dereference pointer "
+ "to member without an object"));
if (noside == EVAL_SKIP)
goto nosideret;
if (unop_user_defined_p (op, arg1))
}
else
{
- struct value *retvalp = evaluate_subexp_for_address (exp, pos, noside);
+ struct value *retvalp = evaluate_subexp_for_address (exp, pos,
+ noside);
return retvalp;
}
{
struct value *tmp = arg1;
- arg2 = value_one (value_type (arg1), not_lval);
+ arg2 = value_one (value_type (arg1));
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
arg2 = value_binop (tmp, arg2, BINOP_ADD);
}
{
struct value *tmp = arg1;
- arg2 = value_one (value_type (arg1), not_lval);
+ arg2 = value_one (value_type (arg1));
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
arg2 = value_binop (tmp, arg2, BINOP_SUB);
}
}
else
{
+ arg3 = value_non_lval (arg1);
+
if (ptrmath_type_p (exp->language_defn, value_type (arg1)))
arg2 = value_ptradd (arg1, 1);
else
{
struct value *tmp = arg1;
- arg2 = value_one (value_type (arg1), not_lval);
+ arg2 = value_one (value_type (arg1));
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
arg2 = value_binop (tmp, arg2, BINOP_ADD);
}
value_assign (arg1, arg2);
- return arg1;
+ return arg3;
}
case UNOP_POSTDECREMENT:
}
else
{
+ arg3 = value_non_lval (arg1);
+
if (ptrmath_type_p (exp->language_defn, value_type (arg1)))
arg2 = value_ptradd (arg1, -1);
else
{
struct value *tmp = arg1;
- arg2 = value_one (value_type (arg1), not_lval);
+ arg2 = value_one (value_type (arg1));
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
arg2 = value_binop (tmp, arg2, BINOP_SUB);
}
value_assign (arg1, arg2);
- return arg1;
+ return arg3;
}
case OP_THIS:
(*pos) += 1;
- return value_of_this (1);
-
- case OP_OBJC_SELF:
- (*pos) += 1;
- return value_of_local ("self", 1);
+ return value_of_this (exp->language_defn);
case OP_TYPE:
/* The value is not supposed to be used. This is here to make it
then they should be separate cases, with more descriptive
error messages. */
- error (_("\
-GDB does not (yet) know how to evaluate that kind of expression"));
+ error (_("GDB does not (yet) know how to "
+ "evaluate that kind of expression"));
}
nosideret:
var = exp->elts[pc + 2].symbol;
/* C++: The "address" of a reference should yield the address
- * of the object pointed to. Let value_addr() deal with it. */
+ * of the object pointed to. Let value_addr() deal with it. */
if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
goto default_case;
return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
not_lval);
else
- error (_("Attempt to take address of value not located in memory."));
+ error (_("Attempt to take address of "
+ "value not located in memory."));
}
return value_addr (x);
}
Note that we currently only do the coercion for C expressions, where
arrays are zero based and the coercion is correct. For other languages,
with nonzero based arrays, coercion loses. Use CAST_IS_CONVERSION
- to decide if coercion is appropriate.
-
- */
+ to decide if coercion is appropriate. */
struct value *
evaluate_subexp_with_coercion (struct expression *exp,
var = exp->elts[pc + 2].symbol;
type = check_typedef (SYMBOL_TYPE (var));
if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && !TYPE_VECTOR (type)
&& CAST_IS_CONVERSION (exp->language_defn))
{
(*pos) += 4;
}
}
-/* Parse a type expression in the string [P..P+LENGTH). */
+/* Parse a type expression in the string [P..P+LENGTH). */
struct type *
parse_and_eval_type (char *p, int length)