/* Evaluate expressions for GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free
- Software Foundation, Inc.
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007
+ Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "gdb_string.h"
#include "block.h"
#include "parser-defs.h"
#include "cp-support.h"
+#include "ui-out.h"
+#include "exceptions.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
/* This is defined in valops.c */
extern int overload_resolution;
fieldno++)
{
char *field_name = TYPE_FIELD_NAME (struct_type, fieldno);
- if (field_name != NULL && DEPRECATED_STREQ (field_name, label))
+ if (field_name != NULL && strcmp (field_name, label) == 0)
{
variantno = -1;
subfieldno = fieldno;
subfieldno < TYPE_NFIELDS (substruct_type);
subfieldno++)
{
- if (DEPRECATED_STREQ (TYPE_FIELD_NAME (substruct_type,
+ if (strcmp(TYPE_FIELD_NAME (substruct_type,
subfieldno),
- label))
+ label) == 0)
{
goto found;
}
if (variantno < 0)
{
fieldno++;
+ /* Skip static fields. */
+ while (fieldno < TYPE_NFIELDS (struct_type)
+ && TYPE_FIELD_STATIC_KIND (struct_type, fieldno))
+ fieldno++;
subfieldno = fieldno;
if (fieldno >= TYPE_NFIELDS (struct_type))
error (_("too many initializers"));
return index;
}
+struct value *
+value_f90_subarray (struct value *array,
+ struct expression *exp, int *pos, enum noside noside)
+{
+ int pc = (*pos) + 1;
+ LONGEST low_bound, high_bound;
+ struct type *range = check_typedef (TYPE_INDEX_TYPE (value_type (array)));
+ enum f90_range_type range_type = longest_to_int (exp->elts[pc].longconst);
+
+ *pos += 3;
+
+ if (range_type == LOW_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
+ low_bound = TYPE_LOW_BOUND (range);
+ else
+ low_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+
+ if (range_type == HIGH_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
+ high_bound = TYPE_HIGH_BOUND (range);
+ else
+ high_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+
+ return value_slice (array, low_bound, high_bound - low_bound + 1);
+}
+
struct value *
evaluate_subexp_standard (struct type *expect_type,
struct expression *exp, int *pos,
case OP_SCOPE:
tem = longest_to_int (exp->elts[pc + 2].longconst);
(*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
arg1 = value_aggregate_elt (exp->elts[pc + 1].type,
&exp->elts[pc + 3].string,
- noside);
+ 0, noside);
if (arg1 == NULL)
error (_("There is no field named %s"), &exp->elts[pc + 3].string);
return arg1;
value_rtti_target_type () if we are dealing with a pointer
or reference to a base class and print object is on. */
- return value_of_variable (exp->elts[pc + 2].symbol,
- exp->elts[pc + 1].block);
+ {
+ volatile struct gdb_exception except;
+ struct value *ret = NULL;
+
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ ret = value_of_variable (exp->elts[pc + 2].symbol,
+ exp->elts[pc + 1].block);
+ }
+
+ if (except.reason < 0)
+ {
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ ret = value_zero (SYMBOL_TYPE (exp->elts[pc + 2].symbol), not_lval);
+ else
+ throw_exception (except);
+ }
+
+ return ret;
+ }
case OP_LAST:
(*pos) += 2;
case OP_REGISTER:
{
int regno = longest_to_int (exp->elts[pc + 1].longconst);
- struct value *val = value_of_register (regno, get_selected_frame (NULL));
+ struct value *val;
(*pos) += 2;
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ val = value_zero (register_type (current_gdbarch, regno), not_lval);
+ else
+ val = value_of_register (regno, get_selected_frame (NULL));
if (val == NULL)
error (_("Value of register %s not available."),
frame_map_regnum_to_name (get_selected_frame (NULL), regno));
argvec = (struct value **) alloca (sizeof (struct value *) * (nargs + 3));
if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
{
- LONGEST fnptr;
-
/* 1997-08-01 Currently we do not support function invocation
via pointers-to-methods with HP aCC. Pointer does not point
to the function, but possibly to some thunk. */
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- fnptr = value_as_long (arg1);
+ if (TYPE_CODE (check_typedef (value_type (arg1)))
+ != TYPE_CODE_METHODPTR)
+ error (_("Non-pointer-to-member value used in pointer-to-member "
+ "construct"));
- if (METHOD_PTR_IS_VIRTUAL (fnptr))
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
- int fnoffset = METHOD_PTR_TO_VOFFSET (fnptr);
- struct type *basetype;
- struct type *domain_type =
- TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (value_type (arg1)));
- int i, j;
- basetype = TYPE_TARGET_TYPE (value_type (arg2));
- if (domain_type != basetype)
- arg2 = value_cast (lookup_pointer_type (domain_type), arg2);
- basetype = TYPE_VPTR_BASETYPE (domain_type);
- for (i = TYPE_NFN_FIELDS (basetype) - 1; i >= 0; i--)
- {
- struct fn_field *f = TYPE_FN_FIELDLIST1 (basetype, i);
- /* If one is virtual, then all are virtual. */
- if (TYPE_FN_FIELD_VIRTUAL_P (f, 0))
- for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j)
- if ((int) TYPE_FN_FIELD_VOFFSET (f, j) == fnoffset)
- {
- 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 (i < 0)
- error (_("virtual function at index %d not found"), fnoffset);
+ struct type *method_type = check_typedef (value_type (arg1));
+ arg1 = value_zero (method_type, not_lval);
}
else
- {
- deprecated_set_value_type (arg1, lookup_pointer_type (TYPE_TARGET_TYPE (value_type (arg1))));
- }
- got_it:
+ arg1 = cplus_method_ptr_to_value (&arg2, arg1);
/* Now, say which argument to start evaluating from */
tem = 2;
type = check_typedef (value_type (arg1));
code = TYPE_CODE (type);
+ if (code == TYPE_CODE_PTR)
+ {
+ /* Fortran always passes variable to subroutines as pointer.
+ So we need to look into its target type to see if it is
+ array, string or function. If it is, we need to switch
+ to the target value the original one points to. */
+ struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (TYPE_CODE (target_type) == TYPE_CODE_ARRAY
+ || TYPE_CODE (target_type) == TYPE_CODE_STRING
+ || TYPE_CODE (target_type) == TYPE_CODE_FUNC)
+ {
+ arg1 = value_ind (arg1);
+ type = check_typedef (value_type (arg1));
+ code = TYPE_CODE (type);
+ }
+ }
+
switch (code)
{
case TYPE_CODE_ARRAY:
- goto multi_f77_subscript;
+ if (exp->elts[*pos].opcode == OP_F90_RANGE)
+ return value_f90_subarray (arg1, exp, pos, noside);
+ else
+ goto multi_f77_subscript;
case TYPE_CODE_STRING:
- goto op_f77_substr;
+ if (exp->elts[*pos].opcode == OP_F90_RANGE)
+ return value_f90_subarray (arg1, exp, pos, noside);
+ else
+ {
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ return value_subscript (arg1, arg2);
+ }
case TYPE_CODE_PTR:
case TYPE_CODE_FUNC:
error (_("Cannot perform substring on this type"));
}
- op_f77_substr:
- /* We have a substring operation on our hands here,
- let us get the string we will be dealing with */
-
- /* Now evaluate the 'from' and 'to' */
-
- arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
-
- if (nargs < 2)
- return value_subscript (arg1, arg2);
-
- arg3 = evaluate_subexp_with_coercion (exp, pos, noside);
-
- if (noside == EVAL_SKIP)
- goto nosideret;
-
- tem2 = value_as_long (arg2);
- tem3 = value_as_long (arg3);
-
- return value_slice (arg1, tem2, tem3 - tem2 + 1);
-
case OP_COMPLEX:
/* We have a complex number, There should be 2 floating
point numbers that compose it */
}
case STRUCTOP_MEMBER:
- arg1 = evaluate_subexp_for_address (exp, pos, noside);
+ case STRUCTOP_MPTR:
+ if (op == STRUCTOP_MEMBER)
+ arg1 = evaluate_subexp_for_address (exp, pos, noside);
+ else
+ arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- /* With HP aCC, pointers to methods do not point to the function code */
- if (deprecated_hp_som_som_object_present &&
- (TYPE_CODE (value_type (arg2)) == TYPE_CODE_PTR) &&
- (TYPE_CODE (TYPE_TARGET_TYPE (value_type (arg2))) == TYPE_CODE_METHOD))
- error (_("Pointers to methods not supported with HP aCC")); /* 1997-08-19 */
+ if (noside == EVAL_SKIP)
+ goto nosideret;
- mem_offset = value_as_long (arg2);
- goto handle_pointer_to_member;
+ type = check_typedef (value_type (arg2));
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_METHODPTR:
+ if (deprecated_hp_som_som_object_present)
+ {
+ /* With HP aCC, pointers to methods do not point to the
+ function code. */
+ /* 1997-08-19 */
+ error (_("Pointers to methods not supported with HP aCC"));
+ }
- case STRUCTOP_MPTR:
- arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (TYPE_TARGET_TYPE (type), not_lval);
+ else
+ {
+ arg2 = cplus_method_ptr_to_value (&arg1, arg2);
+ gdb_assert (TYPE_CODE (value_type (arg2)) == TYPE_CODE_PTR);
+ return value_ind (arg2);
+ }
- /* With HP aCC, pointers to methods do not point to the function code */
- if (deprecated_hp_som_som_object_present &&
- (TYPE_CODE (value_type (arg2)) == TYPE_CODE_PTR) &&
- (TYPE_CODE (TYPE_TARGET_TYPE (value_type (arg2))) == TYPE_CODE_METHOD))
- error (_("Pointers to methods not supported with HP aCC")); /* 1997-08-19 */
+ case TYPE_CODE_MEMBERPTR:
+ /* Now, convert these values to an address. */
+ arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
+ arg1);
- mem_offset = value_as_long (arg2);
+ mem_offset = value_as_long (arg2);
+ if (deprecated_hp_som_som_object_present)
+ {
+ /* HP aCC generates offsets that have bit #29 set; turn it off to get
+ a real offset to the member. */
+ if (!mem_offset) /* no bias -> really null */
+ error (_("Attempted dereference of null pointer-to-member"));
+ mem_offset &= ~0x20000000;
+ }
- handle_pointer_to_member:
- /* HP aCC generates offsets that have bit #29 set; turn it off to get
- a real offset to the member. */
- if (deprecated_hp_som_som_object_present)
- {
- if (!mem_offset) /* no bias -> really null */
- error (_("Attempted dereference of null pointer-to-member"));
- mem_offset &= ~0x20000000;
+ arg3 = value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
+ value_as_long (arg1) + mem_offset);
+ return value_ind (arg3);
+
+ default:
+ error (_("non-pointer-to-member value used in pointer-to-member construct"));
}
- if (noside == EVAL_SKIP)
- goto nosideret;
- type = check_typedef (value_type (arg2));
- if (TYPE_CODE (type) != TYPE_CODE_PTR)
- goto bad_pointer_to_member;
- type = check_typedef (TYPE_TARGET_TYPE (type));
- if (TYPE_CODE (type) == TYPE_CODE_METHOD)
- error (_("not implemented: pointer-to-method in pointer-to-member construct"));
- if (TYPE_CODE (type) != TYPE_CODE_MEMBER)
- goto bad_pointer_to_member;
- /* Now, convert these values to an address. */
- arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
- arg1);
- 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:
- error (_("non-pointer-to-member value used in pointer-to-member construct"));
case BINOP_CONCAT:
arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
the implementation yet; but the pointer appears to point to a code
sequence (thunk) in memory -- in any case it is *not* the address
of the function as it would be in a naive implementation. */
- if ((TYPE_CODE (value_type (arg1)) == TYPE_CODE_PTR) &&
- (TYPE_CODE (TYPE_TARGET_TYPE (value_type (arg1))) == TYPE_CODE_METHOD))
+ if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_METHODPTR)
error (_("Assignment to pointers to methods not implemented with HP aCC"));
- /* HP aCC pointers to data members require a constant bias */
- if ((TYPE_CODE (value_type (arg1)) == TYPE_CODE_PTR) &&
- (TYPE_CODE (TYPE_TARGET_TYPE (value_type (arg1))) == TYPE_CODE_MEMBER))
+ /* HP aCC pointers to data members require a constant bias. */
+ if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_MEMBERPTR)
{
unsigned int *ptr = (unsigned int *) value_contents (arg2); /* forces evaluation */
*ptr |= 0x20000000; /* set 29th bit */
else
return value_sub (arg1, arg2);
+ case BINOP_EXP:
case BINOP_MUL:
case BINOP_DIV:
case BINOP_REM:
if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR)
expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type));
arg1 = evaluate_subexp (expect_type, exp, pos, noside);
- if ((TYPE_TARGET_TYPE (value_type (arg1))) &&
- ((TYPE_CODE (TYPE_TARGET_TYPE (value_type (arg1))) == TYPE_CODE_METHOD) ||
- (TYPE_CODE (TYPE_TARGET_TYPE (value_type (arg1))) == TYPE_CODE_MEMBER)))
+ 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"));
if (noside == EVAL_SKIP)
goto nosideret;
if (noside == EVAL_SKIP)
{
- if (op == OP_SCOPE)
- {
- int temm = longest_to_int (exp->elts[pc + 3].longconst);
- (*pos) += 3 + BYTES_TO_EXP_ELEM (temm + 1);
- }
- else
- evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+ evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
goto nosideret;
}
else
{
struct value *retvalp = evaluate_subexp_for_address (exp, pos, noside);
/* If HP aCC object, use bias for pointers to members */
- if (deprecated_hp_som_som_object_present &&
- (TYPE_CODE (value_type (retvalp)) == TYPE_CODE_PTR) &&
- (TYPE_CODE (TYPE_TARGET_TYPE (value_type (retvalp))) == TYPE_CODE_MEMBER))
+ if (deprecated_hp_som_som_object_present
+ && TYPE_CODE (value_type (retvalp)) == TYPE_CODE_MEMBERPTR)
{
unsigned int *ptr = (unsigned int *) value_contents (retvalp); /* forces evaluation */
*ptr |= 0x20000000; /* set 29th bit */
return value_at_lazy (exp->elts[pc + 1].type,
value_as_address (arg1));
+ case UNOP_MEMVAL_TLS:
+ (*pos) += 3;
+ arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (exp->elts[pc + 2].type, lval_memory);
+ else
+ {
+ CORE_ADDR tls_addr;
+ tls_addr = target_translate_tls_address (exp->elts[pc + 1].objfile,
+ value_as_address (arg1));
+ return value_at_lazy (exp->elts[pc + 2].type, tls_addr);
+ }
+
case UNOP_PREINCREMENT:
arg1 = evaluate_subexp (expect_type, exp, pos, noside);
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return value_of_local ("self", 1);
case OP_TYPE:
- error (_("Attempt to use a type name as an expression"));
+ /* The value is not supposed to be used. This is here to make it
+ easier to accommodate expressions that contain types. */
+ (*pos) += 2;
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return allocate_value (exp->elts[pc + 1].type);
+ else
+ error (_("Attempt to use a type name as an expression"));
default:
/* Removing this case and compiling with gcc -Wall reveals that
enum exp_opcode op;
int pc;
struct symbol *var;
+ struct value *x;
+ int tem;
pc = (*pos);
op = exp->elts[pc].opcode;
{
case UNOP_IND:
(*pos)++;
- return evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ x = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+ /* We can't optimize out "&*" if there's a user-defined operator*. */
+ if (unop_user_defined_p (op, x))
+ {
+ x = value_x_unop (x, op, noside);
+ goto default_case_after_eval;
+ }
+
+ return x;
case UNOP_MEMVAL:
(*pos) += 3;
(var,
block_innermost_frame (exp->elts[pc + 1].block));
+ case OP_SCOPE:
+ tem = longest_to_int (exp->elts[pc + 2].longconst);
+ (*pos) += 5 + BYTES_TO_EXP_ELEM (tem + 1);
+ x = value_aggregate_elt (exp->elts[pc + 1].type,
+ &exp->elts[pc + 3].string,
+ 1, noside);
+ if (x == NULL)
+ error (_("There is no field named %s"), &exp->elts[pc + 3].string);
+ return x;
+
default:
default_case:
+ x = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ default_case_after_eval:
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
- struct value *x = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ struct type *type = check_typedef (value_type (x));
+
if (VALUE_LVAL (x) == lval_memory)
return value_zero (lookup_pointer_type (value_type (x)),
not_lval);
+ else if (TYPE_CODE (type) == TYPE_CODE_REF)
+ return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
+ not_lval);
else
error (_("Attempt to take address of non-lval"));
}
- return value_addr (evaluate_subexp (NULL_TYPE, exp, pos, noside));
+ return value_addr (x);
}
}