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

📄 valarith.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Perform arithmetic and other operations on values, for GDB.   Copyright 1986, 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 "value.h"#include "symtab.h"#include "gdbtypes.h"#include "expression.h"#include "target.h"#include <string.h>static valuevalue_subscripted_rvalue PARAMS ((value, value));valuevalue_add (arg1, arg2)	value arg1, arg2;{  register value valint, valptr;  register int len;  COERCE_ARRAY (arg1);  COERCE_ARRAY (arg2);  if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR       || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR)      &&      (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT       || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT))    /* Exactly one argument is a pointer, and one is an integer.  */    {      if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)	{	  valptr = arg1;	  valint = arg2;	}      else	{	  valptr = arg2;	  valint = arg1;	}      len = TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (valptr)));      if (len == 0) len = 1;	/* For (void *) */      return value_from_longest (VALUE_TYPE (valptr),			      value_as_long (valptr)			      + (len * value_as_long (valint)));    }  return value_binop (arg1, arg2, BINOP_ADD);}valuevalue_sub (arg1, arg2)	value arg1, arg2;{  COERCE_ARRAY (arg1);  COERCE_ARRAY (arg2);  if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)    {      if (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_INT)	{	  /* pointer - integer.  */	  return value_from_longest	    (VALUE_TYPE (arg1),	     value_as_long (arg1)	     - (TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)))		* value_as_long (arg2)));	}      else if (VALUE_TYPE (arg1) == VALUE_TYPE (arg2))	{	  /* pointer to <type x> - pointer to <type x>.  */	  return value_from_longest	    (builtin_type_long,		/* FIXME -- should be ptrdiff_t */	     (value_as_long (arg1) - value_as_long (arg2))	     / TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))));	}      else	{	  error ("\First argument of `-' is a pointer and second argument is neither\n\an integer nor a pointer of the same type.");	}    }  return value_binop (arg1, arg2, BINOP_SUB);}/* Return the value of ARRAY[IDX].  */valuevalue_subscript (array, idx)     value array, idx;{  if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_ARRAY      && VALUE_LVAL (array) != lval_memory)    return value_subscripted_rvalue (array, idx);  else    return value_ind (value_add (array, idx));}/* Return the value of EXPR[IDX], expr an aggregate rvalue   (eg, a vector register).  This routine used to promote floats   to doubles, but no longer does.  */static valuevalue_subscripted_rvalue (array, idx)     value array, idx;{  struct type *elt_type = TYPE_TARGET_TYPE (VALUE_TYPE (array));  int elt_size = TYPE_LENGTH (elt_type);  int elt_offs = elt_size * longest_to_int (value_as_long (idx));  value v;  if (elt_offs >= TYPE_LENGTH (VALUE_TYPE (array)))    error ("no such vector element");  v = allocate_value (elt_type);  memcpy (VALUE_CONTENTS (v), VALUE_CONTENTS (array) + elt_offs, elt_size);  if (VALUE_LVAL (array) == lval_internalvar)    VALUE_LVAL (v) = lval_internalvar_component;  else    VALUE_LVAL (v) = not_lval;  VALUE_ADDRESS (v) = VALUE_ADDRESS (array);  VALUE_OFFSET (v) = VALUE_OFFSET (array) + elt_offs;  VALUE_BITSIZE (v) = elt_size * 8;  return v;}/* Check to see if either argument is a structure.  This is called so   we know whether to go ahead with the normal binop or look for a    user defined function instead.   For now, we do not overload the `=' operator.  */intbinop_user_defined_p (op, arg1, arg2)     enum exp_opcode op;     value arg1, arg2;{  if (op == BINOP_ASSIGN)    return 0;  return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT	  || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT	  || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF	      && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT)	  || (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_REF	      && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_STRUCT));}/* Check to see if argument is a structure.  This is called so   we know whether to go ahead with the normal unop or look for a    user defined function instead.   For now, we do not overload the `&' operator.  */int unop_user_defined_p (op, arg1)     enum exp_opcode op;     value arg1;{  if (op == UNOP_ADDR)    return 0;  return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT	  || (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF	      && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT));}/* We know either arg1 or arg2 is a structure, so try to find the right   user defined function.  Create an argument vector that calls    arg1.operator @ (arg1,arg2) and return that value (where '@' is any   binary operator which is legal for GNU C++).   OP is the operatore, and if it is BINOP_ASSIGN_MODIFY, then OTHEROP   is the opcode saying how to modify it.  Otherwise, OTHEROP is   unused.  */valuevalue_x_binop (arg1, arg2, op, otherop)     value arg1, arg2;     enum exp_opcode op, otherop;{  value * argvec;  char *ptr;  char tstr[13];  int static_memfuncp;  COERCE_REF (arg1);  COERCE_REF (arg2);  COERCE_ENUM (arg1);  COERCE_ENUM (arg2);  /* now we know that what we have to do is construct our     arg vector and find the right function to call it with.  */  if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)    error ("Can't do that binary op on that type");  /* FIXME be explicit */  argvec = (value *) alloca (sizeof (value) * 4);  argvec[1] = value_addr (arg1);  argvec[2] = arg2;  argvec[3] = 0;  /* make the right function name up */    strcpy(tstr, "operator__");  ptr = tstr+8;  switch (op)    {    case BINOP_ADD:	strcpy(ptr,"+"); break;    case BINOP_SUB:	strcpy(ptr,"-"); break;    case BINOP_MUL:	strcpy(ptr,"*"); break;    case BINOP_DIV:	strcpy(ptr,"/"); break;    case BINOP_REM:	strcpy(ptr,"%"); break;    case BINOP_LSH:	strcpy(ptr,"<<"); break;    case BINOP_RSH:	strcpy(ptr,">>"); break;    case BINOP_LOGAND:	strcpy(ptr,"&"); break;    case BINOP_LOGIOR:	strcpy(ptr,"|"); break;    case BINOP_LOGXOR:	strcpy(ptr,"^"); break;    case BINOP_AND:	strcpy(ptr,"&&"); break;    case BINOP_OR:	strcpy(ptr,"||"); break;    case BINOP_MIN:	strcpy(ptr,"<?"); break;    case BINOP_MAX:	strcpy(ptr,">?"); break;    case BINOP_ASSIGN:	strcpy(ptr,"="); break;    case BINOP_ASSIGN_MODIFY:	      switch (otherop)	{	case BINOP_ADD:      strcpy(ptr,"+="); break;	case BINOP_SUB:      strcpy(ptr,"-="); break;	case BINOP_MUL:      strcpy(ptr,"*="); break;	case BINOP_DIV:      strcpy(ptr,"/="); break;	case BINOP_REM:      strcpy(ptr,"%="); break;	case BINOP_LOGAND:   strcpy(ptr,"&="); break;	case BINOP_LOGIOR:   strcpy(ptr,"|="); break;	case BINOP_LOGXOR:   strcpy(ptr,"^="); break;	default:	  error ("Invalid binary operation specified.");	}      break;    case BINOP_SUBSCRIPT: strcpy(ptr,"[]"); break;    case BINOP_EQUAL:	  strcpy(ptr,"=="); break;    case BINOP_NOTEQUAL:  strcpy(ptr,"!="); break;    case BINOP_LESS:      strcpy(ptr,"<"); break;    case BINOP_GTR:       strcpy(ptr,">"); break;    case BINOP_GEQ:       strcpy(ptr,">="); break;    case BINOP_LEQ:       strcpy(ptr,"<="); break;    default:      error ("Invalid binary operation specified.");    }  argvec[0] = value_struct_elt (&arg1, argvec+1, tstr, &static_memfuncp, "structure");  if (argvec[0])    {      if (static_memfuncp)	{	  argvec[1] = argvec[0];	  argvec++;	}      return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1);    }  error ("member function %s not found", tstr);#ifdef lint  return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1);#endif}/* We know that arg1 is a structure, so try to find a unary user   defined operator that matches the operator in question.     Create an argument vector that calls arg1.operator @ (arg1)   and return that value (where '@' is (almost) any unary operator which   is legal for GNU C++).  */valuevalue_x_unop (arg1, op)     value arg1;     enum exp_opcode op;{  value * argvec;  char *ptr;  char tstr[13];  int static_memfuncp;  COERCE_ENUM (arg1);  /* now we know that what we have to do is construct our     arg vector and find the right function to call it with.  */  if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)    error ("Can't do that unary op on that type");  /* FIXME be explicit */  argvec = (value *) alloca (sizeof (value) * 3);  argvec[1] = value_addr (arg1);  argvec[2] = 0;  /* make the right function name up */    strcpy(tstr,"operator__");  ptr = tstr+8;  switch (op)    {    case UNOP_PREINCREMENT:	strcpy(ptr,"++"); break;    case UNOP_PREDECREMENT:	strcpy(ptr,"++"); break;    case UNOP_POSTINCREMENT:	strcpy(ptr,"++"); break;    case UNOP_POSTDECREMENT:	strcpy(ptr,"++"); break;    case UNOP_ZEROP:	strcpy(ptr,"!"); break;    case UNOP_LOGNOT:	strcpy(ptr,"~"); break;    case UNOP_NEG:	strcpy(ptr,"-"); break;    default:      error ("Invalid binary operation specified.");    }  argvec[0] = value_struct_elt (&arg1, argvec+1, tstr, &static_memfuncp, "structure");  if (argvec[0])    {      if (static_memfuncp)	{	  argvec[1] = argvec[0];	  argvec++;	}      return call_function_by_hand (argvec[0], 1 - static_memfuncp, argvec + 1);    }  error ("member function %s not found", tstr);  return 0;  /* For lint -- never reached */}/* Perform a binary operation on two integers or two floats.   Does not support addition and subtraction on pointers;   use value_add or value_sub if you want to handle those possibilities.  */valuevalue_binop (arg1, arg2, op)     value arg1, arg2;     enum exp_opcode op;{  register value val;  COERCE_ENUM (arg1);  COERCE_ENUM (arg2);  if ((TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_FLT       &&

⌨️ 快捷键说明

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