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

📄 typeck.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
	tree list = NULL_TREE;	HOST_WIDE_INT min_index = 0, max_index, cur_index;	if (element_size == 1 && CH_CHARS_TYPE_P (type))	  {	    value = build_string (size, buffer);	    CH_DERIVED_FLAG (value) = 1;	    TREE_TYPE (value) = type;	    return value;	  }	if (TYPE_DOMAIN (type) == 0)	  return 0;	value = TYPE_MIN_VALUE (TYPE_DOMAIN (type));	if (value)	  {	    if (TREE_CODE (value) != INTEGER_CST)	      return 0;	    else	      min_index = TREE_INT_CST_LOW (value);	  }	value = TYPE_MAX_VALUE (TYPE_DOMAIN (type));	if (value == NULL_TREE || TREE_CODE (value) != INTEGER_CST)	  return 0;	else	  max_index = TREE_INT_CST_LOW (value);	for (cur_index = max_index; cur_index >= min_index; cur_index--)	  {	    HOST_WIDE_INT offset = (cur_index - min_index) * element_size;	    value = extract_constant_from_buffer (element_type,						  buffer + offset,						  buf_size - offset);	    if (value == NULL_TREE)	      return NULL_TREE;	    list = tree_cons (build_int_2 (cur_index, 0), value, list);	  }	value = build (CONSTRUCTOR, type, NULL_TREE, list);	TREE_CONSTANT (value) = 1;	TREE_STATIC (value) = 1;	return value;      }    case RECORD_TYPE:      {	tree list = NULL_TREE;	tree field = TYPE_FIELDS (type);	for (; field != NULL_TREE; field = TREE_CHAIN (field))	  {	    HOST_WIDE_INT offset	      = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) / BITS_PER_UNIT;	    if (DECL_BIT_FIELD (field))	      return 0;	    value = extract_constant_from_buffer (TREE_TYPE (field),						  buffer + offset,						  buf_size - offset);	    if (value == NULL_TREE)	      return NULL_TREE;	    list = tree_cons (field, value, list);	  }	value = build (CONSTRUCTOR, type, NULL_TREE, nreverse (list));	TREE_CONSTANT (value) = 1;	TREE_STATIC (value) = 1;	return value;      }    case UNION_TYPE:      {	tree longest_variant = NULL_TREE;	int longest_size = 0;	tree field = TYPE_FIELDS (type);		/* This is a kludge.  We assume that converting the data to te	   longest variant will provide valid data for the "correct"	   variant.  This is usually the case, but is not guaranteed.	   For example, the longest variant may include holes.	   Also incorrect interpreting the given value as the longest	   variant may confuse the compiler if that should happen	   to yield invalid values.  ??? */	for (; field != NULL_TREE; field = TREE_CHAIN (field))	  {	    int size = TREE_INT_CST_LOW (size_in_bytes (TREE_TYPE (field)));	    	    if (size > longest_size)	      {		longest_size = size;		longest_variant = field;	      }	  }	if (longest_variant == NULL_TREE)	  return NULL_TREE;	return extract_constant_from_buffer (TREE_TYPE (longest_variant), buffer, buf_size);      }    case SET_TYPE:      {	tree list = NULL_TREE;	int i;	HOST_WIDE_INT min_index, max_index;	if (TYPE_DOMAIN (type) == 0)	  return 0;	value = TYPE_MIN_VALUE (TYPE_DOMAIN (type));	if (value == NULL_TREE)	  min_index = 0;	else if (TREE_CODE (value) != INTEGER_CST)	  return 0;	else	  min_index = TREE_INT_CST_LOW (value);	value = TYPE_MAX_VALUE (TYPE_DOMAIN (type));	if (value == NULL_TREE)	  max_index = 0;	else if (TREE_CODE (value) != INTEGER_CST)	  return 0;	else	  max_index = TREE_INT_CST_LOW (value);	for (i = max_index + 1 - min_index; --i >= 0; )	  {	    unsigned char byte = (unsigned char)buffer[i / BITS_PER_UNIT];	    unsigned bit_pos = (unsigned)i % (unsigned)BITS_PER_UNIT;	    if (BYTES_BIG_ENDIAN		? (byte & (1 << (BITS_PER_UNIT - 1 - bit_pos)))		: (byte & (1 << bit_pos)))	      list = tree_cons (NULL_TREE,				build_int_2 (i + min_index, 0), list);	  }	value = build (CONSTRUCTOR, type, NULL_TREE, list);	TREE_CONSTANT (value) = 1;	TREE_STATIC (value) = 1;	return value;      }    default:      return NULL_TREE;    }}treebuild_chill_cast (type, expr)     tree type, expr;{  tree expr_type;  int  expr_type_size;  int  type_size;  int  type_is_discrete;  int  expr_type_is_discrete;  if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)    return error_mark_node;  if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)    return error_mark_node;  /* if expression was untyped because of its context (an     if_expr or case_expr in a tuple, perhaps) just apply     the type */  expr_type = TREE_TYPE (expr);  if (expr_type == NULL_TREE      || TREE_CODE (expr_type) == ERROR_MARK)    return convert (type, expr);  if (expr_type == type)    return expr;  expr_type_size = int_size_in_bytes (expr_type);  type_size      = int_size_in_bytes (type);  if (expr_type_size == -1)    {      error ("conversions from variable_size value");      return error_mark_node;    }  if (type_size == -1)    {      error ("conversions to variable_size mode");      return error_mark_node;    }  /* FIXME: process REAL ==> INT && INT ==> REAL && REAL ==> REAL. I hope this is correct. */  if ((TREE_CODE (expr_type) == INTEGER_TYPE && TREE_CODE (type) == REAL_TYPE) ||      (TREE_CODE (expr_type) == REAL_TYPE && TREE_CODE (type) == INTEGER_TYPE) ||      (TREE_CODE (expr_type) == REAL_TYPE && TREE_CODE (type) == REAL_TYPE))    return convert (type, expr);  /* FIXME: Don't know if this is correct */  /* Don't allow conversions to or from REAL with others then integer */  if (TREE_CODE (type) == REAL_TYPE)    {      error ("cannot convert to float");      return error_mark_node;    }  else if (TREE_CODE (expr_type) == REAL_TYPE)    {      error ("cannot convert float to this mode");      return error_mark_node;    }  if (expr_type_size == type_size && CH_REFERABLE (expr))    goto do_location_conversion;  type_is_discrete    = discrete_type_p (type) || TREE_CODE (type) == POINTER_TYPE;  expr_type_is_discrete    = discrete_type_p (expr_type) || TREE_CODE (expr_type) == POINTER_TYPE;  if (expr_type_is_discrete && type_is_discrete)    {      /* do an overflow check	 FIXME: is this always neccessary ??? */      /* FIXME: don't do range chacking when target type is PTR.	 PTR doesn't have MIN and MAXVALUE. result is sigsegv. */      if (range_checking && type != ptr_type_node)	{	  tree tmp = expr;	  STRIP_NOPS (tmp);	  if (TREE_CONSTANT (tmp) && TREE_CODE (tmp) != ADDR_EXPR)	    {	      if (compare_int_csts (LT_EXPR, tmp, TYPE_MIN_VALUE (type)) ||		  compare_int_csts (GT_EXPR, tmp, TYPE_MAX_VALUE (type)))		{		  error ("OVERFLOW in expression conversion");		  return error_mark_node;		}	    }	  else	    {	      int cond1 = tree_int_cst_lt (TYPE_SIZE (type),					   TYPE_SIZE (expr_type));	      int cond2 = TREE_UNSIGNED (type) && (! TREE_UNSIGNED (expr_type));	      int cond3 = (! TREE_UNSIGNED (type))		&& TREE_UNSIGNED (expr_type)		&& tree_int_cst_equal (TYPE_SIZE (type),				       TYPE_SIZE (expr_type));	      int cond4 = TREE_TYPE (type) && type_is_discrete;	      if (cond1 || cond2 || cond3 || cond4)		{		  tree type_min = TYPE_MIN_VALUE (type);		  tree type_max = TYPE_MAX_VALUE (type);  		  expr = save_if_needed (expr);		  if (expr && type_min && type_max)		    {		      tree check = test_range (expr, type_min, type_max);		      if (!integer_zerop (check))			{			  if (current_function_decl == NULL_TREE)			    {			      if (TREE_CODE (check) == INTEGER_CST)				error ("overflow (not inside function)");			      else				warning ("possible overflow (not inside function)");			    }			  else			    {			      if (TREE_CODE (check) == INTEGER_CST)				warning ("expression will always cause OVERFLOW");			      expr = check_expression (expr, check,						       ridpointers[(int) RID_OVERFLOW]);			    }			}		    }		}	    }	}      return convert (type, expr);    }  if (TREE_CODE (expr) == INTEGER_CST && expr_type_size != type_size)    {      /* There should probably be a pedwarn here ... */      tree itype = type_for_size (type_size * BITS_PER_UNIT, 1);      if (itype)	{	  expr = convert (itype, expr);	  expr_type = TREE_TYPE (expr);	  expr_type_size= type_size;	}    }  /* If expr is a constant of the right size, use it to to     initialize a static variable. */  if (expr_type_size == type_size && TREE_CONSTANT (expr) && !pedantic)    {      unsigned char *buffer = (unsigned char*) alloca (type_size);      tree value;      bzero (buffer, type_size);      if (!expand_constant_to_buffer (expr, buffer, type_size))	{	  error ("not implemented: constant conversion from that kind of expression");	  return error_mark_node;	}      value = extract_constant_from_buffer (type, buffer, type_size);      if (value == NULL_TREE)	{	  error ("not implemented: constant conversion to that kind of mode");	  return error_mark_node;	}      return value;    }  if (!CH_REFERABLE (expr) && expr_type_size == type_size)    {      tree temp = decl_temp1 (get_unique_identifier ("CAST"),			      TREE_TYPE (expr), 0, 0, 0, 0);      tree convert1 = build_chill_modify_expr (temp, expr);      pedwarn ("non-standard, non-portable value conversion");      return build (COMPOUND_EXPR, type, convert1,		    build_chill_cast (type, temp));    }  if (CH_REFERABLE (expr) && expr_type_size != type_size)    error ("location conversion between differently-sized modes");  else    error ("unsupported value conversion");  return error_mark_node; do_location_conversion:  /* To avoid confusing other parts of gcc,     represent this as the C expression: *(TYPE*)EXPR. */  mark_addressable (expr);  expr = build1 (INDIRECT_REF, type,		 build1 (NOP_EXPR, build_pointer_type (type),			 build1 (ADDR_EXPR, build_pointer_type (expr_type),				 expr)));  TREE_READONLY (expr) = TYPE_READONLY (type);  return expr;}/* * given a set_type, build an integer array from it that C will grok. */treebuild_array_from_set (type)     tree type;{  tree bytespint, bit_array_size, int_array_count;   if (type == NULL_TREE || type == error_mark_node || TREE_CODE (type) != SET_TYPE)    return error_mark_node;  bytespint = build_int_2 (HOST_BITS_PER_INT / HOST_BITS_PER_CHAR, 0);  bit_array_size = size_in_bytes (type);  int_array_count = fold (size_binop (TRUNC_DIV_EXPR, bit_array_size,						 bytespint));  if (integer_zerop (int_array_count))    int_array_count = size_one_node;  type = build_array_type (integer_type_node, 			   build_index_type (int_array_count));  return type;}treebuild_chill_bin_type (size)     tree size;{#if 0  int isize;  if (TREE_CODE (size) != INTEGER_CST      || (isize = TREE_INT_CST_LOW (size), isize <= 0))    {      error ("operand to bin must be a non-negative integer literal");      return error_mark_node;    }  if (isize <= TYPE_PRECISION (unsigned_char_type_node))    return unsigned_char_type_node;  if (isize <= TYPE_PRECISION (short_unsigned_type_node))    return short_unsigned_type_node;  if (isize <= TYPE_PRECISION (unsigned_type_node))    return unsigned_type_node;  if (isize <= TYPE_PRECISION (long_unsigned_type_node))    return long_unsigned_type_node;  if (isize <= TYPE_PRECISION (long_long_unsigned_type_node))    return long_long_unsigned_type_node;  error ("size %d of BIN too big - no such integer mode", isize);  return error_mark_node;#endif  tree bintype;   if (pass == 1)    {      bintype = make_node (INTEGER_TYPE);      TREE_TYPE (bintype) = ridpointers[(int) RID_BIN];      TYPE_MIN_VALUE (bintype) = size;      TYPE_MAX_VALUE (bintype) = size;    }  else    {      error ("BIN in pass 2");      return error_mark_node;    }  return bintype;}treechill_expand_tuple (type, constructor)     tree type, constructor;{  char *name;  tree nonreft = type;  if (TYPE_NAME (type) != NULL_TREE)    {      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)	name = IDENTIFIER_POINTER (TYPE_NAME (type));      else	name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));    }  else    name = "";  /* get to actual underlying type for digest_init */  while (nonreft && TREE_CODE (nonreft) == REFERENCE_TYPE)    nonreft = TREE_TYPE (nonreft);  if (TREE_CODE (nonreft) == ARRAY_TYPE      || TREE_CODE (nonreft) == RECORD_TYPE      || TREE_CODE (nonreft) == SET_TYPE)    return convert (nonreft, constructor);  else    {      error ("mode of tuple is neither ARRAY, STRUCT, nor POWERSET");      return error_mark_node;    }}/* This function classifies an expr into the Null class,   the All class, the M-Value, the M-derived, or the M-reference class.   It probably has some inaccuracies. */struct ch_classchill_expr_class (expr)     tree expr;{  struct ch_class class;  /* The Null class contains the NULL pointer constant (only). */  if (expr == null_pointer_node)    {      class.kind = CH_NULL_CLASS;      class.mode = NULL_TREE;      return class;    }  /* The All class contains the <undefined value> "*". */  if (TREE_CODE (expr) == UNDEFINED_EXPR)    {      class.kind = CH_ALL_CLASS;      class.mode = NULL_TREE;      return class;    }

⌨️ 快捷键说明

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