⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eval.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	}      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 + -