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

📄 eval.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Evaluate expressions for GDB.   Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "defs.h"#include "symtab.h"#include "gdbtypes.h"#include "value.h"#include "expression.h"#include "target.h"#include "frame.h"/* Values of NOSIDE argument to eval_subexp.  */enum noside{ EVAL_NORMAL,  EVAL_SKIP,			/* Only effect is to increment pos.  */  EVAL_AVOID_SIDE_EFFECTS	/* Don't modify any variables or				   call any functions.  The value				   returned will have the correct				   type, and will have an				   approximately correct lvalue				   type (inaccuracy: anything that is				   listed as being in a register in				   the function in which it was				   declared will be lval_register).  */};/* Prototypes for local functions. */static valueevaluate_subexp_for_sizeof PARAMS ((struct expression *, int *));static valueevaluate_subexp_with_coercion PARAMS ((struct expression *, int *,				       enum noside));static valueevaluate_subexp_for_address PARAMS ((struct expression *, int *,				     enum noside));static valueevaluate_subexp PARAMS ((struct type *, struct expression *, int *,			 enum noside));/* Parse the string EXP as a C expression, evaluate it,   and return the result as a number.  */CORE_ADDRparse_and_eval_address (exp)     char *exp;{  struct expression *expr = parse_expression (exp);  register CORE_ADDR addr;  register struct cleanup *old_chain =       make_cleanup (free_current_contents, &expr);  addr = value_as_pointer (evaluate_expression (expr));  do_cleanups (old_chain);  return addr;}/* Like parse_and_eval_address but takes a pointer to a char * variable   and advanced that variable across the characters parsed.  */CORE_ADDRparse_and_eval_address_1 (expptr)     char **expptr;{  struct expression *expr = parse_exp_1 (expptr, (struct block *)0, 0);  register CORE_ADDR addr;  register struct cleanup *old_chain =      make_cleanup (free_current_contents, &expr);  addr = value_as_pointer (evaluate_expression (expr));  do_cleanups (old_chain);  return addr;}valueparse_and_eval (exp)     char *exp;{  struct expression *expr = parse_expression (exp);  register value val;  register struct cleanup *old_chain    = make_cleanup (free_current_contents, &expr);  val = evaluate_expression (expr);  do_cleanups (old_chain);  return val;}/* Parse up to a comma (or to a closeparen)   in the string EXPP as an expression, evaluate it, and return the value.   EXPP is advanced to point to the comma.  */valueparse_to_comma_and_eval (expp)     char **expp;{  struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1);  register value val;  register struct cleanup *old_chain    = make_cleanup (free_current_contents, &expr);  val = evaluate_expression (expr);  do_cleanups (old_chain);  return val;}/* Evaluate an expression in internal prefix form   such as is constructed by parse.y.   See expression.h for info on the format of an expression.  */static value evaluate_subexp ();static value evaluate_subexp_for_address ();static value evaluate_subexp_for_sizeof ();static value evaluate_subexp_with_coercion ();/* return true if 'var' has an address in inferior's memory. */static intvalue_has_lval(var)	register struct symbol *var;{  switch (SYMBOL_CLASS(var))    {    case LOC_STATIC:    case LOC_LABEL:    case LOC_ARG:    case LOC_REF_ARG:    case LOC_LOCAL:    case LOC_BLOCK:      return (1);    }  return (0);}valueevaluate_expression (exp)     struct expression *exp;{  int pc = 0;  return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_NORMAL);}/* Evaluate an expression, avoiding all memory references   and getting a value whose type alone is correct.  */valueevaluate_type (exp)     struct expression *exp;{  int pc = 0;  return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);}static valueevaluate_subexp (expect_type, exp, pos, noside)     struct type *expect_type;     register struct expression *exp;     register int *pos;     enum noside noside;{  enum exp_opcode op;  int tem;  register int pc, pc2, oldpos;  register value arg1, arg2, arg3;  struct type *type;  int nargs;  value *argvec;  pc = (*pos)++;  op = exp->elts[pc].opcode;  switch (op)    {    case OP_SCOPE:      tem = strlen (&exp->elts[pc + 2].string);      (*pos) += 3 + ((tem + sizeof (union exp_element))		     / sizeof (union exp_element));      arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,					     0,					     exp->elts[pc + 1].type,					     &exp->elts[pc + 2].string,					     expect_type);      if (arg1 == NULL)	error ("There is no field named %s", &exp->elts[pc + 2].string);      return arg1;    case OP_LONG:      (*pos) += 3;      return value_from_longest (exp->elts[pc + 1].type,			      exp->elts[pc + 2].longconst);    case OP_DOUBLE:      (*pos) += 3;      return value_from_double (exp->elts[pc + 1].type,				exp->elts[pc + 2].doubleconst);    case OP_VAR_VALUE:      (*pos) += 2;      if (noside == EVAL_SKIP)	goto nosideret;      if (noside == EVAL_AVOID_SIDE_EFFECTS)	{	  struct symbol * sym = exp->elts[pc + 1].symbol;	  enum lval_type lv;	  switch (SYMBOL_CLASS (sym))	    {	    case LOC_CONST:	    case LOC_LABEL:	    case LOC_CONST_BYTES:	      lv = not_lval;	      break;	    case LOC_REGISTER:	    case LOC_REGPARM:	      lv = lval_register;	      break;	    default:	      lv = lval_memory;	      break;	    }	  return value_zero (SYMBOL_TYPE (sym), lv);	}      else	return value_of_variable (exp->elts[pc + 1].symbol);    case OP_LAST:      (*pos) += 2;      return	access_value_history (longest_to_int (exp->elts[pc + 1].longconst));    case OP_REGISTER:      (*pos) += 2;      return value_of_register (longest_to_int (exp->elts[pc + 1].longconst));    case OP_INTERNALVAR:      (*pos) += 2;      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));      if (noside == EVAL_SKIP)	goto nosideret;      return value_string (&exp->elts[pc + 1].string, tem);    case TERNOP_COND:      /* Skip third and second args to evaluate the first one.  */      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);      if (value_zerop (arg1))	{	  evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);	  return evaluate_subexp (NULL_TYPE, exp, pos, noside);	}      else	{	  arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);	  evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);	  return arg2;	}    case OP_FUNCALL:      (*pos) += 2;      op = exp->elts[*pos].opcode;      if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)	{	  int fnptr;	  nargs = longest_to_int (exp->elts[pc + 1].longconst) + 1;	  /* First, evaluate the structure into arg2 */	  pc2 = (*pos)++;	  if (noside == EVAL_SKIP)	    goto nosideret;	  if (op == STRUCTOP_MEMBER)	    {	      arg2 = evaluate_subexp_for_address (exp, pos, noside);	    }	  else	    {	      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);	    }	  /* If the function is a virtual function, then the	     aggregate value (providing the structure) plays	     its part by providing the vtable.  Otherwise,	     it is just along for the ride: call the function	     directly.  */	  arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);	  fnptr = longest_to_int (value_as_long (arg1));	  if (METHOD_PTR_IS_VIRTUAL(fnptr))	    {	      int fnoffset = METHOD_PTR_TO_VOFFSET(fnptr);	      struct type *basetype;	      struct type *domain_type =		  TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)));	      int i, j;	      basetype = TYPE_TARGET_TYPE (VALUE_TYPE (arg2));	      if (domain_type != basetype)		  arg2 = value_cast(lookup_pointer_type (domain_type), arg2);	      basetype = TYPE_VPTR_BASETYPE (domain_type);	      for (i = TYPE_NFN_FIELDS (basetype) - 1; i >= 0; i--)		{		  struct fn_field *f = TYPE_FN_FIELDLIST1 (basetype, i);		  /* If one is virtual, then all are virtual.  */		  if (TYPE_FN_FIELD_VIRTUAL_P (f, 0))		    for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j)		      if (TYPE_FN_FIELD_VOFFSET (f, j) == fnoffset)			{			  value temp = value_ind (arg2);			  arg1 = value_virtual_fn_field (&temp, f, j, domain_type, 0);			  arg2 = value_addr (temp);			  goto got_it;			}		}	      if (i < 0)		error ("virtual function at index %d not found", fnoffset);	    }	  else	    {	      VALUE_TYPE (arg1) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)));	    }	got_it:	  /* Now, say which argument to start evaluating from */	  tem = 2;	}      else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)	{	  /* Hair for method invocations */	  int tem2;	  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);	  if (noside == EVAL_SKIP)	    goto nosideret;	  if (op == STRUCTOP_STRUCT)	    {	      arg2 = evaluate_subexp_for_address (exp, pos, noside);	    }	  else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -