/* Perform arithmetic and other operations on values, for GDB.
- Copyright 1986, 1989, 1991, 1992, 1993, 1994
+ Copyright 1986, 89, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
static value_ptr value_subscripted_rvalue PARAMS ((value_ptr, value_ptr, int));
+void _initialize_valarith PARAMS ((void));
+
\f
value_ptr
value_add (arg1, arg2)
|| TYPE_CODE (type2) == TYPE_CODE_INT))
/* Exactly one argument is a pointer, and one is an integer. */
{
+ value_ptr retval;
+
if (TYPE_CODE (type1) == TYPE_CODE_PTR)
{
valptr = arg1;
valptrtype = type2;
}
len = TYPE_LENGTH (check_typedef (TYPE_TARGET_TYPE (valptrtype)));
- if (len == 0) len = 1; /* For (void *) */
- return value_from_longest (valptrtype,
- value_as_long (valptr)
- + (len * value_as_long (valint)));
+ if (len == 0)
+ len = 1; /* For (void *) */
+ retval = value_from_longest (valptrtype,
+ value_as_long (valptr)
+ + (len * value_as_long (valint)));
+ VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (valptr);
+ return retval;
}
return value_binop (arg1, arg2, BINOP_ADD);
{
value_ptr bound;
int c_style = current_language->c_style_arrays;
- struct type *tarray, *tint;
+ struct type *tarray;
COERCE_REF (array);
tarray = check_typedef (VALUE_TYPE (array));
LONGEST index = value_as_long (idx);
value_ptr v;
int offset, byte, bit_index;
- LONGEST lowerbound, upperbound, word;
+ LONGEST lowerbound, upperbound;
get_discrete_bounds (range_type, &lowerbound, &upperbound);
if (index < lowerbound || index > upperbound)
error ("bitstring index out of range");
{
struct type *array_type = check_typedef (VALUE_TYPE (array));
struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
- int elt_size = TYPE_LENGTH (elt_type);
+ unsigned int elt_size = TYPE_LENGTH (elt_type);
LONGEST index = value_as_long (idx);
- int elt_offs = elt_size * longest_to_int (index - lowerbound);
+ unsigned int elt_offs = elt_size * longest_to_int (index - lowerbound);
value_ptr v;
if (index < lowerbound || elt_offs >= TYPE_LENGTH (array_type))
unused. */
value_ptr
-value_x_binop (arg1, arg2, op, otherop)
+value_x_binop (arg1, arg2, op, otherop, noside)
value_ptr arg1, arg2;
enum exp_opcode op, otherop;
+ enum noside noside;
{
value_ptr * argvec;
char *ptr;
argvec[1] = argvec[0];
argvec++;
}
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct type *return_type;
+ return_type
+ = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0])));
+ return value_zero (return_type, VALUE_LVAL (arg1));
+ }
return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1);
}
error ("member function %s not found", tstr);
is legal for GNU C++). */
value_ptr
-value_x_unop (arg1, op)
+value_x_unop (arg1, op, noside)
value_ptr arg1;
enum exp_opcode op;
+ enum noside noside;
{
value_ptr * argvec;
char *ptr, *mangle_ptr;
case UNOP_LOGICAL_NOT: strcpy(ptr,"!"); break;
case UNOP_COMPLEMENT: strcpy(ptr,"~"); break;
case UNOP_NEG: strcpy(ptr,"-"); break;
+ case UNOP_IND: strcpy(ptr,"*"); break;
default:
- error ("Invalid binary operation specified.");
+ error ("Invalid unary operation specified.");
}
argvec[0] = value_struct_elt (&arg1, argvec+1, tstr, &static_memfuncp, "structure");
argvec[1] = argvec[0];
argvec++;
}
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct type *return_type;
+ return_type
+ = TYPE_TARGET_TYPE (check_typedef (VALUE_TYPE (argvec[0])));
+ return value_zero (return_type, VALUE_LVAL (arg1));
+ }
return call_function_by_hand (argvec[0], 1 - static_memfuncp, argvec + 1);
}
error ("member function %s not found", tstr);
/* FIXME: This implements ANSI C rules (also correct for C++).
What about FORTRAN and chill? */
{
- int promoted_len1 = TYPE_LENGTH (type1);
- int promoted_len2 = TYPE_LENGTH (type2);
+ unsigned int promoted_len1 = TYPE_LENGTH (type1);
+ unsigned int promoted_len2 = TYPE_LENGTH (type2);
int is_unsigned1 = TYPE_UNSIGNED (type1);
int is_unsigned2 = TYPE_UNSIGNED (type2);
- int result_len;
+ unsigned int result_len;
int unsigned_operation;
/* Determine type length and signedness after promotion for
if (unsigned_operation)
{
- unsigned LONGEST v1, v2, v;
- v1 = (unsigned LONGEST) value_as_long (arg1);
- v2 = (unsigned LONGEST) value_as_long (arg2);
+ ULONGEST v1, v2, v;
+ v1 = (ULONGEST) value_as_long (arg1);
+ v2 = (ULONGEST) value_as_long (arg2);
/* Truncate values to the type length of the result. */
- if (result_len < sizeof (unsigned LONGEST))
+ if (result_len < sizeof (ULONGEST))
{
v1 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1;
v2 &= ((LONGEST) 1 << HOST_CHAR_BIT * result_len) - 1;
code1 = TYPE_CODE (type1);
code2 = TYPE_CODE (type2);
- if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
+ if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) &&
+ (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return longest_to_int (value_as_long (value_binop (arg1, arg2,
BINOP_EQUAL)));
- else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
- && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
+ else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)
+ && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return value_as_double (arg1) == value_as_double (arg2);
/* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
is bigger. */
- else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
+ else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return value_as_pointer (arg1) == (CORE_ADDR) value_as_long (arg2);
- else if (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT)
+ else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
return (CORE_ADDR) value_as_long (arg1) == value_as_pointer (arg2);
else if (code1 == code2
- && ((len = TYPE_LENGTH (type1))
- == TYPE_LENGTH (type2)))
+ && ((len = (int) TYPE_LENGTH (type1))
+ == (int) TYPE_LENGTH (type2)))
{
p1 = VALUE_CONTENTS (arg1);
p2 = VALUE_CONTENTS (arg2);
code1 = TYPE_CODE (type1);
code2 = TYPE_CODE (type2);
- if (code1 == TYPE_CODE_INT && code2 == TYPE_CODE_INT)
+ if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL) &&
+ (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return longest_to_int (value_as_long (value_binop (arg1, arg2,
BINOP_LESS)));
- else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT)
- && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT))
+ else if ((code1 == TYPE_CODE_FLT || code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL)
+ && (code2 == TYPE_CODE_FLT || code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return value_as_double (arg1) < value_as_double (arg2);
else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
return value_as_pointer (arg1) < value_as_pointer (arg2);
/* FIXME: Need to promote to either CORE_ADDR or LONGEST, whichever
is bigger. */
- else if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_INT)
+ else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL))
return value_as_pointer (arg1) < (CORE_ADDR) value_as_long (arg2);
- else if (code2 == TYPE_CODE_PTR && code1 == TYPE_CODE_INT)
+ else if (code2 == TYPE_CODE_PTR && (code1 == TYPE_CODE_INT || code1 == TYPE_CODE_BOOL))
return (CORE_ADDR) value_as_long (arg1) < value_as_pointer (arg2);
else
register value_ptr arg1;
{
register struct type *type;
+ register struct type *result_type = VALUE_TYPE (arg1);
COERCE_REF (arg1);
COERCE_ENUM (arg1);
type = check_typedef (VALUE_TYPE (arg1));
if (TYPE_CODE (type) == TYPE_CODE_FLT)
- return value_from_double (type, - value_as_double (arg1));
- else if (TYPE_CODE (type) == TYPE_CODE_INT)
- return value_from_longest (type, - value_as_long (arg1));
+ return value_from_double (result_type, - value_as_double (arg1));
+ else if (TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_BOOL)
+ {
+ /* Perform integral promotion for ANSI C/C++.
+ FIXME: What about FORTRAN and chill ? */
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ result_type = builtin_type_int;
+
+ return value_from_longest (result_type, - value_as_long (arg1));
+ }
else {
error ("Argument to negate operation not a number.");
return 0; /* For lint -- never reached */
value_complement (arg1)
register value_ptr arg1;
{
+ register struct type *type;
+ register struct type *result_type = VALUE_TYPE (arg1);
+ int typecode;
+
COERCE_REF (arg1);
COERCE_ENUM (arg1);
- if (TYPE_CODE (check_typedef (VALUE_TYPE (arg1))) != TYPE_CODE_INT)
- error ("Argument to complement operation not an integer.");
+ type = check_typedef (VALUE_TYPE (arg1));
+
+ typecode = TYPE_CODE (type);
+ if ((typecode != TYPE_CODE_INT) && (typecode != TYPE_CODE_BOOL))
+ error ("Argument to complement operation not an integer or boolean.");
+
+ /* Perform integral promotion for ANSI C/C++.
+ FIXME: What about FORTRAN ? */
+ if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
+ result_type = builtin_type_int;
- return value_from_longest (VALUE_TYPE (arg1), ~ value_as_long (arg1));
+ return value_from_longest (result_type, ~ value_as_long (arg1));
}
\f
/* The INDEX'th bit of SET value whose VALUE_TYPE is TYPE,
value_as_long (element));
if (member < 0)
error ("First argument of 'IN' not in range");
- return value_from_longest (builtin_type_chill_bool, member);
+ return value_from_longest (LA_BOOL_TYPE, member);
}
void