📄 eval.c
字号:
} else { tem = value_less (arg1, arg2) || value_equal (arg1, arg2); return value_from_longest (builtin_type_int, (LONGEST) tem); } case BINOP_REPEAT: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_INT) error ("Non-integral right operand for \"@\" operator."); if (noside == EVAL_AVOID_SIDE_EFFECTS) return allocate_repeat_value (VALUE_TYPE (arg1), longest_to_int (value_as_long (arg2))); else return value_repeat (arg1, longest_to_int (value_as_long (arg2))); case BINOP_COMMA: evaluate_subexp (NULL_TYPE, exp, pos, noside); return evaluate_subexp (NULL_TYPE, exp, pos, noside); case UNOP_NEG: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; if (unop_user_defined_p (op, arg1)) return value_x_unop (arg1, op); else return value_neg (arg1); case UNOP_LOGNOT: /* C++: check for and handle destructor names. */ op = exp->elts[*pos].opcode; arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; if (unop_user_defined_p (UNOP_LOGNOT, arg1)) return value_x_unop (arg1, UNOP_LOGNOT); else return value_lognot (arg1); case UNOP_ZEROP: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; if (unop_user_defined_p (op, arg1)) return value_x_unop (arg1, op); else return value_from_longest (builtin_type_int, (LONGEST) value_zerop (arg1)); case UNOP_IND: if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR) expect_type = TYPE_TARGET_TYPE (expect_type); arg1 = evaluate_subexp (expect_type, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; if (noside == EVAL_AVOID_SIDE_EFFECTS) { if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF /* In C you can dereference an array to get the 1st elt. */ || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_ARRAY ) return value_zero (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)), lval_memory); else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT) /* GDB allows dereferencing an int. */ return value_zero (builtin_type_int, lval_memory); else error ("Attempt to take contents of a non-pointer value."); } return value_ind (arg1); case UNOP_ADDR: /* C++: check for and handle pointer to members. */ op = exp->elts[*pos].opcode; if (noside == EVAL_SKIP) { 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); } else evaluate_subexp (expect_type, exp, pos, EVAL_SKIP); goto nosideret; } return evaluate_subexp_for_address (exp, pos, noside); case UNOP_SIZEOF: if (noside == EVAL_SKIP) { evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP); goto nosideret; } return evaluate_subexp_for_sizeof (exp, pos); case UNOP_CAST: (*pos) += 2; arg1 = evaluate_subexp (expect_type, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; return value_cast (exp->elts[pc + 1].type, arg1); case UNOP_MEMVAL: (*pos) += 2; 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 + 1].type, lval_memory); else return value_at_lazy (exp->elts[pc + 1].type, value_as_pointer (arg1)); case UNOP_PREINCREMENT: arg1 = evaluate_subexp (expect_type, exp, pos, noside); if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; else if (unop_user_defined_p (op, arg1)) { return value_x_unop (arg1, op); } else { arg2 = value_add (arg1, value_from_longest (builtin_type_char, (LONGEST) 1)); return value_assign (arg1, arg2); } case UNOP_PREDECREMENT: arg1 = evaluate_subexp (expect_type, exp, pos, noside); if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; else if (unop_user_defined_p (op, arg1)) { return value_x_unop (arg1, op); } else { arg2 = value_sub (arg1, value_from_longest (builtin_type_char, (LONGEST) 1)); return value_assign (arg1, arg2); } case UNOP_POSTINCREMENT: arg1 = evaluate_subexp (expect_type, exp, pos, noside); if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; else if (unop_user_defined_p (op, arg1)) { return value_x_unop (arg1, op); } else { arg2 = value_add (arg1, value_from_longest (builtin_type_char, (LONGEST) 1)); value_assign (arg1, arg2); return arg1; } case UNOP_POSTDECREMENT: arg1 = evaluate_subexp (expect_type, exp, pos, noside); if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; else if (unop_user_defined_p (op, arg1)) { return value_x_unop (arg1, op); } else { arg2 = value_sub (arg1, value_from_longest (builtin_type_char, (LONGEST) 1)); value_assign (arg1, arg2); return arg1; } case OP_THIS: (*pos) += 1; return value_of_this (1); default: error ("internal error: I do not know how to evaluate what you gave me"); } nosideret: return value_from_longest (builtin_type_long, (LONGEST) 1);}/* Evaluate a subexpression of EXP, at index *POS, and return the address of that subexpression. Advance *POS over the subexpression. If the subexpression isn't an lvalue, get an error. NOSIDE may be EVAL_AVOID_SIDE_EFFECTS; then only the type of the result need be correct. */static valueevaluate_subexp_for_address (exp, pos, noside) register struct expression *exp; register int *pos; enum noside noside;{ enum exp_opcode op; register int pc; struct symbol *var; pc = (*pos); op = exp->elts[pc].opcode; switch (op) { case UNOP_IND: (*pos)++; return evaluate_subexp (NULL_TYPE, exp, pos, noside); case UNOP_MEMVAL: (*pos) += 3; return value_cast (lookup_pointer_type (exp->elts[pc + 1].type), evaluate_subexp (NULL_TYPE, exp, pos, noside)); case OP_VAR_VALUE: var = exp->elts[pc + 1].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; if (noside == EVAL_AVOID_SIDE_EFFECTS) { struct type *type = lookup_pointer_type (SYMBOL_TYPE (var)); enum address_class sym_class = SYMBOL_CLASS (var); if (sym_class == LOC_CONST || sym_class == LOC_CONST_BYTES || sym_class == LOC_REGISTER || sym_class == LOC_REGPARM) error ("Attempt to take address of register or constant."); return value_zero (type, not_lval); } else return locate_var_value (var, (FRAME) 0); default: default_case: if (noside == EVAL_AVOID_SIDE_EFFECTS) { value x = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (VALUE_LVAL (x) == lval_memory) return value_zero (lookup_pointer_type (VALUE_TYPE (x)), not_lval); else error ("Attempt to take address of non-lval"); } return value_addr (evaluate_subexp (NULL_TYPE, 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. */static valueevaluate_subexp_with_coercion (exp, pos, noside) register struct expression *exp; register int *pos; enum noside noside;{ register enum exp_opcode op; register int pc; register value val; struct symbol *var; pc = (*pos); op = exp->elts[pc].opcode; switch (op) { case OP_VAR_VALUE: var = exp->elts[pc + 1].symbol; if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY) { (*pos) += 3; val = locate_var_value (var, (FRAME) 0); return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (var))), val); } default: return evaluate_subexp (NULL_TYPE, exp, pos, noside); }}/* Evaluate a subexpression of EXP, at index *POS, and return a value for the size of that subexpression. Advance *POS over the subexpression. */static valueevaluate_subexp_for_sizeof (exp, pos) register struct expression *exp; register int *pos;{ enum exp_opcode op; register int pc; value val; pc = (*pos); op = exp->elts[pc].opcode; switch (op) { /* This case is handled specially so that we avoid creating a value for the result type. If the result type is very big, it's desirable not to create a value unnecessarily. */ case UNOP_IND: (*pos)++; val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); return value_from_longest (builtin_type_int, (LONGEST) TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (val)))); case UNOP_MEMVAL: (*pos) += 3; return value_from_longest (builtin_type_int, (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))); default: val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS); return value_from_longest (builtin_type_int, (LONGEST) TYPE_LENGTH (VALUE_TYPE (val))); }}/* Parse a type expression in the string [P..P+LENGTH). */struct type *parse_and_eval_type (p, length) char *p; int length;{ char *tmp = (char *)alloca (length + 4); struct expression *expr; tmp[0] = '('; memcpy (tmp+1, p, length); tmp[length+1] = ')'; tmp[length+2] = '0'; tmp[length+3] = '\0'; expr = parse_expression (tmp); if (expr->elts[0].opcode != UNOP_CAST) error ("Internal error in eval_type."); return expr->elts[1].type;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -