#include "expression.h"
#include "target.h"
#include "frame.h"
+#include "demangle.h"
#include "language.h" /* For CAST_IS_CONVERSION */
/* Values of NOSIDE argument to eval_subexp. */
enum noside noside;
{
enum exp_opcode op;
- int tem;
- register int pc, pc2, oldpos;
- register value arg1, arg2, arg3;
+ int tem, tem2, tem3;
+ register int pc, pc2 = 0, oldpos;
+ register value arg1 = NULL, arg2 = NULL, arg3;
struct type *type;
int nargs;
value *argvec;
{
case OP_SCOPE:
tem = longest_to_int (exp->elts[pc + 2].longconst);
- (*pos) += 4 + ((tem + sizeof (union exp_element))
- / sizeof (union exp_element));
+ (*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 + 2].doubleconst);
case OP_VAR_VALUE:
- (*pos) += 2;
+ (*pos) += 3;
if (noside == EVAL_SKIP)
goto nosideret;
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
- struct symbol * sym = exp->elts[pc + 1].symbol;
+ struct symbol * sym = exp->elts[pc + 2].symbol;
enum lval_type lv;
switch (SYMBOL_CLASS (sym))
return value_zero (SYMBOL_TYPE (sym), lv);
}
else
- return value_of_variable (exp->elts[pc + 1].symbol);
+ return value_of_variable (exp->elts[pc + 2].symbol,
+ exp->elts[pc + 1].block);
case OP_LAST:
(*pos) += 2;
(*pos) += 2;
return value_of_register (longest_to_int (exp->elts[pc + 1].longconst));
- /* start-sanitize-chill */
case OP_BOOL:
(*pos) += 2;
return value_from_longest (builtin_type_chill_bool,
exp->elts[pc + 1].longconst);
- /* end-sanitize-chill */
case OP_INTERNALVAR:
(*pos) += 2;
case OP_STRING:
tem = longest_to_int (exp->elts[pc + 1].longconst);
- (*pos) += 3 + ((tem + sizeof (union exp_element))
- / sizeof (union exp_element));
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
if (noside == EVAL_SKIP)
goto nosideret;
return value_string (&exp->elts[pc + 2].string, tem);
+ case OP_BITSTRING:
+ error ("support for OP_BITSTRING unimplemented");
+ break;
+
+ case OP_ARRAY:
+ (*pos) += 3;
+ tem2 = longest_to_int (exp->elts[pc + 1].longconst);
+ tem3 = longest_to_int (exp->elts[pc + 2].longconst);
+ nargs = tem3 - tem2 + 1;
+ argvec = (value *) alloca (sizeof (value) * nargs);
+ for (tem = 0; tem < nargs; tem++)
+ {
+ /* Ensure that array expressions are coerced into pointer objects. */
+ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
+ }
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ return (value_array (tem2, tem3, argvec));
+ break;
+
case TERNOP_COND:
/* Skip third and second args to evaluate the first one. */
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
/* First, evaluate the structure into arg2 */
pc2 = (*pos)++;
tem2 = longest_to_int (exp->elts[pc2 + 1].longconst);
- *pos += 3 + (tem2 + sizeof (union exp_element)) / sizeof (union exp_element);
+ *pos += 3 + BYTES_TO_EXP_ELEM (tem2 + 1);
if (noside == EVAL_SKIP)
goto nosideret;
if (op == STRUCTOP_STRUCT)
{
+ /* If v is a variable in a register, and the user types
+ v.method (), this will produce an error, because v has
+ no address.
+
+ A possible way around this would be to allocate a
+ copy of the variable on the stack, copy in the
+ contents, call the function, and copy out the
+ contents. I.e. convert this from call by reference
+ to call by copy-return (or whatever it's called).
+ However, this does not work because it is not the
+ same: the method being called could stash a copy of
+ the address, and then future uses through that address
+ (after the method returns) would be expected to
+ use the variable itself, not some copy of it. */
arg2 = evaluate_subexp_for_address (exp, pos, noside);
}
else
nargs = longest_to_int (exp->elts[pc + 1].longconst);
tem = 0;
}
+ /* Allocate arg vector, including space for the function to be
+ called in argvec[0] and a terminating NULL */
argvec = (value *) alloca (sizeof (value) * (nargs + 2));
for (; tem <= nargs; tem++)
/* Ensure that array expressions are coerced into pointer objects. */
{
int static_memfuncp;
value temp = arg2;
+ char tstr[15], mangle_tstr[15], *ptr, *mangle_ptr;
+ char *pp;
argvec[1] = arg2;
- argvec[0] =
- value_struct_elt (&temp, argvec+1, &exp->elts[pc2 + 2].string,
+ argvec[0] = 0;
+ strcpy(tstr, &exp->elts[pc2+2].string);
+ if (!strncmp(tstr, "operator", 8))
+ {
+ ptr = &tstr[8];
+ strcpy(mangle_tstr, "__");
+ mangle_ptr = &mangle_tstr[2];
+ pp = cplus_mangle_opname(ptr, DMGL_ANSI);
+ if (pp)
+ strcpy(mangle_ptr, pp);
+ else
+ strcpy(mangle_ptr, ptr);
+ argvec[0] =
+ value_struct_elt (&temp, argvec+1, mangle_tstr,
&static_memfuncp,
op == STRUCTOP_STRUCT
? "structure" : "structure pointer");
- if (VALUE_OFFSET (temp))
+ if (!argvec[0])
+ {
+ pp = cplus_mangle_opname(ptr, DMGL_NO_OPTS);
+ if (pp)
+ strcpy(mangle_ptr, pp);
+ else
+ strcpy(mangle_ptr, ptr);
+ strcpy(tstr, mangle_tstr);
+ }
+ }
+ if (!argvec[0])
{
- arg2 = value_from_longest (lookup_pointer_type (VALUE_TYPE (temp)),
- value_as_long (arg2)+VALUE_OFFSET (temp));
- argvec[1] = arg2;
+ temp = arg2;
+ argvec[0] =
+ value_struct_elt (&temp, argvec+1, tstr,
+ &static_memfuncp,
+ op == STRUCTOP_STRUCT
+ ? "structure" : "structure pointer");
}
+ arg2 = value_from_longest (lookup_pointer_type(VALUE_TYPE (temp)),
+ VALUE_ADDRESS (temp)+VALUE_OFFSET (temp));
+ argvec[1] = arg2;
+
if (static_memfuncp)
{
argvec[1] = argvec[0];
case STRUCTOP_STRUCT:
tem = longest_to_int (exp->elts[pc + 1].longconst);
- (*pos) += 3 + ((tem + sizeof (union exp_element))
- / sizeof (union exp_element));
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
case STRUCTOP_PTR:
tem = longest_to_int (exp->elts[pc + 1].longconst);
- (*pos) += 3 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (lookup_struct_elt_type (TYPE_TARGET_TYPE
- (VALUE_TYPE (arg1)),
+ return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1),
&exp->elts[pc + 2].string,
0),
lval_memory);
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);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ if (binop_user_defined_p (op, arg1, arg2))
+ return value_x_binop (arg1, arg2, op, OP_NULL);
+ else
+ return value_concat (arg1, arg2);
+
case BINOP_ASSIGN:
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
if (op == OP_SCOPE)
{
int temm = longest_to_int (exp->elts[pc+3].longconst);
- (*pos) += 3 + (temm + sizeof (union exp_element)) / sizeof (union exp_element);
+ (*pos) += 3 + BYTES_TO_EXP_ELEM (temm + 1);
}
else
evaluate_subexp (expect_type, exp, pos, EVAL_SKIP);
(*pos) += 1;
return value_of_this (1);
+ case OP_TYPE:
+ error ("Attempt to use a type name as an expression");
+
default:
- error ("internal error: I do not know how to evaluate what you gave me");
+ /* 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.
+
+ If there are any cases landing here which mean a user error,
+ then they should be separate cases, with more descriptive
+ error messages. */
+
+ error ("\
+GDB does not (yet) know how to evaluated that kind of expression");
}
nosideret:
evaluate_subexp (NULL_TYPE, exp, pos, noside));
case OP_VAR_VALUE:
- var = exp->elts[pc + 1].symbol;
+ 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. */
if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
goto default_case;
- (*pos) += 3;
+ (*pos) += 4;
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
struct type *type =
value_zero (type, not_lval);
}
else
- return locate_var_value (var, (FRAME) 0);
+ return
+ locate_var_value
+ (var,
+ block_innermost_frame (exp->elts[pc + 1].block));
default:
default_case:
/* Evaluate like `evaluate_subexp' except coercing arrays to pointers.
When used in contexts where arrays will be coerced anyway, this is
equivalent to `evaluate_subexp' but much faster because it avoids
- actually fetching array contents.
+ actually fetching array contents (perhaps obsolete now that we have
+ VALUE_LAZY).
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.
- */
+ */
static value
evaluate_subexp_with_coercion (exp, pos, noside)
switch (op)
{
case OP_VAR_VALUE:
- var = exp->elts[pc + 1].symbol;
+ var = exp->elts[pc + 2].symbol;
if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY
&& CAST_IS_CONVERSION)
{
- (*pos) += 3;
- val = locate_var_value (var, (FRAME) 0);
+ (*pos) += 4;
+ 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))),
val);
}
- default:
- return evaluate_subexp (NULL_TYPE, exp, pos, noside);
+ /* FALLTHROUGH */
+
+ default:
+ return evaluate_subexp (NULL_TYPE, exp, pos, noside);
}
}
(LONGEST) TYPE_LENGTH (exp->elts[pc + 1].type));
case OP_VAR_VALUE:
- (*pos) += 3;
- return value_from_longest (builtin_type_int,
- (LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 1].symbol)));
+ (*pos) += 4;
+ return
+ value_from_longest
+ (builtin_type_int,
+ (LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 2].symbol)));
default:
val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);