X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Feval.c;h=a5a831569b28b19d70996f452a32a0cc4a13b79b;hb=8ed0509162c9a6f44d174b2ff3b59134815496f3;hp=82e02cee09dabe7fd4594a3aedaede3c22879377;hpb=e58de8a23021ce9bbdee715ac79745ebb93437a8;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/eval.c b/gdb/eval.c index 82e02cee09..a5a831569b 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -24,6 +24,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #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 @@ -161,9 +163,9 @@ evaluate_subexp (expect_type, exp, pos, noside) 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; @@ -174,22 +176,21 @@ evaluate_subexp (expect_type, exp, pos, noside) switch (op) { case OP_SCOPE: - tem = strlen (&exp->elts[pc + 2].string); - (*pos) += 3 + ((tem + sizeof (union exp_element)) - / sizeof (union exp_element)); + 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 + 2].string, + &exp->elts[pc + 3].string, expect_type); if (arg1 == NULL) - error ("There is no field named %s", &exp->elts[pc + 2].string); + error ("There is no field named %s", &exp->elts[pc + 3].string); return arg1; case OP_LONG: (*pos) += 3; return value_from_longest (exp->elts[pc + 1].type, - exp->elts[pc + 2].longconst); + exp->elts[pc + 2].longconst); case OP_DOUBLE: (*pos) += 3; @@ -197,12 +198,12 @@ evaluate_subexp (expect_type, exp, pos, noside) 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)) @@ -226,7 +227,8 @@ evaluate_subexp (expect_type, exp, pos, noside) 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; @@ -247,12 +249,31 @@ evaluate_subexp (expect_type, exp, pos, noside) return value_of_internalvar (exp->elts[pc + 1].internalvar); case OP_STRING: - tem = strlen (&exp->elts[pc + 1].string); - (*pos) += 2 + ((tem + sizeof (union exp_element)) - / sizeof (union exp_element)); + tem = longest_to_int (exp->elts[pc + 1].longconst); + (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1); if (noside == EVAL_SKIP) goto nosideret; - return value_string (&exp->elts[pc + 1].string, tem); + 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. */ @@ -347,13 +368,27 @@ evaluate_subexp (expect_type, exp, pos, noside) nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1; /* First, evaluate the structure into arg2 */ pc2 = (*pos)++; - tem2 = strlen (&exp->elts[pc2 + 1].string); - *pos += 2 + (tem2 + sizeof (union exp_element)) / sizeof (union exp_element); + tem2 = longest_to_int (exp->elts[pc2 + 1].longconst); + *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 @@ -368,6 +403,8 @@ evaluate_subexp (expect_type, exp, pos, noside) 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. */ @@ -380,19 +417,50 @@ evaluate_subexp (expect_type, exp, pos, noside) { 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 + 1].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]; @@ -428,40 +496,38 @@ evaluate_subexp (expect_type, exp, pos, noside) return call_function_by_hand (argvec[0], nargs, argvec + 1); case STRUCTOP_STRUCT: - tem = strlen (&exp->elts[pc + 1].string); - (*pos) += 2 + ((tem + sizeof (union exp_element)) - / sizeof (union exp_element)); + tem = longest_to_int (exp->elts[pc + 1].longconst); + (*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 (VALUE_TYPE (arg1), - &exp->elts[pc + 1].string, + &exp->elts[pc + 2].string, 0), lval_memory); else { value temp = arg1; - return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 1].string, + return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 2].string, (int *) 0, "structure"); } case STRUCTOP_PTR: - tem = strlen (&exp->elts[pc + 1].string); - (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); + tem = longest_to_int (exp->elts[pc + 1].longconst); + (*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)), - &exp->elts[pc + 1].string, + return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1), + &exp->elts[pc + 2].string, 0), lval_memory); else { value temp = arg1; - return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 1].string, + return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 2].string, (int *) 0, "structure pointer"); } @@ -490,6 +556,16 @@ evaluate_subexp (expect_type, exp, pos, noside) 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); @@ -540,6 +616,7 @@ evaluate_subexp (expect_type, exp, pos, noside) case BINOP_MUL: case BINOP_DIV: case BINOP_REM: + case BINOP_MOD: case BINOP_LSH: case BINOP_RSH: case BINOP_BITWISE_AND: @@ -553,7 +630,7 @@ evaluate_subexp (expect_type, exp, pos, noside) return value_x_binop (arg1, arg2, op, OP_NULL); else if (noside == EVAL_AVOID_SIDE_EFFECTS - && (op == BINOP_DIV || op == BINOP_REM)) + && (op == BINOP_DIV || op == BINOP_REM || op == BINOP_MOD)) return value_zero (VALUE_TYPE (arg1), not_lval); else return value_binop (arg1, arg2, op); @@ -582,6 +659,57 @@ evaluate_subexp (expect_type, exp, pos, noside) else return value_subscript (arg1, arg2); + case MULTI_SUBSCRIPT: + (*pos) += 2; + nargs = longest_to_int (exp->elts[pc + 1].longconst); + arg1 = evaluate_subexp_with_coercion (exp, pos, noside); + while (nargs-- > 0) + { + arg2 = evaluate_subexp_with_coercion (exp, pos, noside); + /* FIXME: EVAL_SKIP handling may not be correct. */ + if (noside == EVAL_SKIP) + { + if (nargs > 0) + { + continue; + } + else + { + goto nosideret; + } + } + /* 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. */ + + type = TYPE_TARGET_TYPE (VALUE_TYPE (arg1)); + if (type != NULL) + { + arg1 = value_zero (type, VALUE_LVAL (arg1)); + noside = EVAL_SKIP; + continue; + } + else + { + error ("cannot subscript something of type `%s'", + TYPE_NAME (VALUE_TYPE (arg1))); + } + } + + if (binop_user_defined_p (op, arg1, arg2)) + { + arg1 = value_x_binop (arg1, arg2, op, OP_NULL); + } + else + { + arg1 = value_subscript (arg1, arg2); + } + } + return (arg1); + case BINOP_LOGICAL_AND: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) @@ -804,9 +932,8 @@ evaluate_subexp (expect_type, exp, pos, noside) { if (op == OP_SCOPE) { - char *name = &exp->elts[pc+3].string; - int temm = strlen (name); - (*pos) += 2 + (temm + sizeof (union exp_element)) / sizeof (union exp_element); + int temm = longest_to_int (exp->elts[pc+3].longconst); + (*pos) += 3 + BYTES_TO_EXP_ELEM (temm + 1); } else evaluate_subexp (expect_type, exp, pos, EVAL_SKIP); @@ -907,8 +1034,22 @@ evaluate_subexp (expect_type, exp, pos, noside) (*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: @@ -947,14 +1088,14 @@ evaluate_subexp_for_address (exp, pos, noside) 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 = @@ -971,7 +1112,10 @@ evaluate_subexp_for_address (exp, pos, noside) 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: @@ -989,9 +1133,17 @@ evaluate_subexp_for_address (exp, pos, noside) } /* 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. */ + 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 (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) @@ -1010,16 +1162,21 @@ evaluate_subexp_with_coercion (exp, pos, noside) switch (op) { case OP_VAR_VALUE: - var = exp->elts[pc + 1].symbol; - if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY) + 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); } } @@ -1057,9 +1214,11 @@ evaluate_subexp_for_sizeof (exp, pos) (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);