📄 eval.c
字号:
{ arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); } /* Now, say which argument to start evaluating from */ tem = 2; } else { nargs = longest_to_int (exp->elts[pc + 1].longconst); tem = 0; } argvec = (value *) alloca (sizeof (value) * (nargs + 2)); for (; tem <= nargs; tem++) /* Ensure that array expressions are coerced into pointer objects. */ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); /* signal end of arglist */ argvec[tem] = 0; if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) { int static_memfuncp; value temp = arg2; argvec[1] = arg2; argvec[0] = value_struct_elt (&temp, argvec+1, &exp->elts[pc2 + 1].string, &static_memfuncp, op == STRUCTOP_STRUCT ? "structure" : "structure pointer"); if (VALUE_OFFSET (temp)) { arg2 = value_from_longest (lookup_pointer_type (VALUE_TYPE (temp)), value_as_long (arg2)+VALUE_OFFSET (temp)); argvec[1] = arg2; } if (static_memfuncp) { argvec[1] = argvec[0]; nargs--; argvec++; } } else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) { argvec[1] = arg2; argvec[0] = arg1; } if (noside == EVAL_SKIP) goto nosideret; if (noside == EVAL_AVOID_SIDE_EFFECTS) { /* 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 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. */ struct type *ftype = TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0])); if (ftype) return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]))); else error ("Expression of type other than \"Function returning ...\" used as function"); } 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)); /* Try to convert "foo.bar" into "(&foo)->bar" so we won't copy the entire contents of a large struct just to extract one value from it. */ if (noside == EVAL_NORMAL && exp->elts[*pos].opcode == OP_VAR_VALUE && value_has_lval(exp->elts[*pos + 1].symbol)) arg1 = evaluate_subexp_for_address(exp, pos, noside); else arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; if (noside == EVAL_AVOID_SIDE_EFFECTS) { register struct type *type = VALUE_TYPE (arg1); if (TYPE_CODE (type) == TYPE_CODE_PTR) type = TYPE_TARGET_TYPE (type); return value_zero (lookup_struct_elt_type (type, &exp->elts[pc + 1].string, 1), lval_memory); } else { value temp = arg1; return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 1].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); 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, 0), lval_memory); else { value temp = arg1; return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 1].string, (int *) 0, "structure pointer"); } case STRUCTOP_MEMBER: arg1 = evaluate_subexp_for_address (exp, pos, noside); goto handle_pointer_to_member; case STRUCTOP_MPTR: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); handle_pointer_to_member: arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR) goto bad_pointer_to_member; type = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)); 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_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)), value_as_long (arg1) + value_as_long (arg2)); return value_ind (arg3); bad_pointer_to_member: error("non-pointer-to-member value used in pointer-to-member construct"); case BINOP_ASSIGN: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; if (binop_user_defined_p (op, arg1, arg2)) return value_x_binop (arg1, arg2, op, OP_NULL); else return value_assign (arg1, arg2); case BINOP_ASSIGN_MODIFY: (*pos) += 2; arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside); if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; op = exp->elts[pc + 1].opcode; if (binop_user_defined_p (op, arg1, arg2)) return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op); else if (op == BINOP_ADD) arg2 = value_add (arg1, arg2); else if (op == BINOP_SUB) arg2 = value_sub (arg1, arg2); else arg2 = value_binop (arg1, arg2, op); return value_assign (arg1, arg2); case BINOP_ADD: 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_add (arg1, arg2); case BINOP_SUB: 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_sub (arg1, arg2); case BINOP_MUL: case BINOP_DIV: case BINOP_REM: case BINOP_LSH: case BINOP_RSH: case BINOP_LOGAND: case BINOP_LOGIOR: case BINOP_LOGXOR: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (NULL_TYPE, 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 if (noside == EVAL_AVOID_SIDE_EFFECTS && (op == BINOP_DIV || op == BINOP_REM)) return value_zero (VALUE_TYPE (arg1), not_lval); else return value_binop (arg1, arg2, op); case BINOP_SUBSCRIPT: arg1 = evaluate_subexp_with_coercion (exp, pos, noside); arg2 = evaluate_subexp_with_coercion (exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; 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) return value_zero (type, VALUE_LVAL (arg1)); else error ("cannot subscript something of type `%s'", TYPE_NAME (VALUE_TYPE (arg1))); } if (binop_user_defined_p (op, arg1, arg2)) return value_x_binop (arg1, arg2, op, OP_NULL); else return value_subscript (arg1, arg2); case BINOP_AND: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) { arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); goto nosideret; } oldpos = *pos; arg2 = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); *pos = oldpos; if (binop_user_defined_p (op, arg1, arg2)) { arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); return value_x_binop (arg1, arg2, op, OP_NULL); } else { tem = value_zerop (arg1); arg2 = evaluate_subexp (NULL_TYPE, exp, pos, (tem ? EVAL_SKIP : noside)); return value_from_longest (builtin_type_int, (LONGEST) (!tem && !value_zerop (arg2))); } case BINOP_OR: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) { arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); goto nosideret; } oldpos = *pos; arg2 = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); *pos = oldpos; if (binop_user_defined_p (op, arg1, arg2)) { arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); return value_x_binop (arg1, arg2, op, OP_NULL); } else { tem = value_zerop (arg1); arg2 = evaluate_subexp (NULL_TYPE, exp, pos, (!tem ? EVAL_SKIP : noside)); return value_from_longest (builtin_type_int, (LONGEST) (!tem || !value_zerop (arg2))); } case BINOP_EQUAL: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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 { tem = value_equal (arg1, arg2); return value_from_longest (builtin_type_int, (LONGEST) tem); } case BINOP_NOTEQUAL: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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 { tem = value_equal (arg1, arg2); return value_from_longest (builtin_type_int, (LONGEST) ! tem); } case BINOP_LESS: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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 { tem = value_less (arg1, arg2); return value_from_longest (builtin_type_int, (LONGEST) tem); } case BINOP_GTR: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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 { tem = value_less (arg2, arg1); return value_from_longest (builtin_type_int, (LONGEST) tem); } case BINOP_GEQ: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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 { tem = value_less (arg2, arg1) || value_equal (arg1, arg2); return value_from_longest (builtin_type_int, (LONGEST) tem); } case BINOP_LEQ: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (VALUE_TYPE (arg1), 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -