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

📄 c-typeck.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (code == FUNCTION_TYPE)    {      if (pedantic || warn_pointer_arith)	pedwarn ("sizeof applied to a function type");      return size_int (1);    }  if (code == VOID_TYPE)    {      if (pedantic || warn_pointer_arith)	pedwarn ("sizeof applied to a void type");      return size_int (1);    }  if (code == ERROR_MARK)    return size_int (1);  if (TYPE_SIZE (type) == 0)    {      error ("sizeof applied to an incomplete type");      return size_int (0);    }  /* Convert in case a char is more than one unit.  */  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 		  size_int (TYPE_PRECISION (char_type_node)));  /* size_binop does not put the constant in range, so do it now.  */  if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0))    TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1;  return t;}treec_sizeof_nowarn (type)     tree type;{  enum tree_code code = TREE_CODE (type);  tree t;  if (code == FUNCTION_TYPE      || code == VOID_TYPE      || code == ERROR_MARK)    return size_int (1);  if (TYPE_SIZE (type) == 0)    return size_int (0);  /* Convert in case a char is more than one unit.  */  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 		  size_int (TYPE_PRECISION (char_type_node)));  force_fit_type (t, 0);  return t;}/* Compute the size to increment a pointer by.  */treec_size_in_bytes (type)     tree type;{  enum tree_code code = TREE_CODE (type);  tree t;  if (code == FUNCTION_TYPE)    return size_int (1);  if (code == VOID_TYPE)    return size_int (1);  if (code == ERROR_MARK)    return size_int (1);  if (TYPE_SIZE (type) == 0)    {      error ("arithmetic on pointer to an incomplete type");      return size_int (1);    }  /* Convert in case a char is more than one unit.  */  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 		     size_int (BITS_PER_UNIT));  force_fit_type (t, 0);  return t;}/* Implement the __alignof keyword: Return the minimum required   alignment of TYPE, measured in bytes.  */treec_alignof (type)     tree type;{  enum tree_code code = TREE_CODE (type);  if (code == FUNCTION_TYPE)    return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);  if (code == VOID_TYPE || code == ERROR_MARK)    return size_int (1);  return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);}/* Implement the __alignof keyword: Return the minimum required   alignment of EXPR, measured in bytes.  For VAR_DECL's and   FIELD_DECL's return DECL_ALIGN (which can be set from an   "aligned" __attribute__ specification).  */treec_alignof_expr (expr)     tree expr;{  if (TREE_CODE (expr) == VAR_DECL)    return size_int (DECL_ALIGN (expr) / BITS_PER_UNIT);   if (TREE_CODE (expr) == COMPONENT_REF      && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))    {      error ("`__alignof' applied to a bit-field");      return size_int (1);    }  else if (TREE_CODE (expr) == COMPONENT_REF      && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)    return size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT);   if (TREE_CODE (expr) == INDIRECT_REF)    {      tree t = TREE_OPERAND (expr, 0);      tree best = t;      int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));       while (TREE_CODE (t) == NOP_EXPR	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)	{	  int thisalign;	  t = TREE_OPERAND (t, 0);	  thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));	  if (thisalign > bestalign)	    best = t, bestalign = thisalign;	}      return c_alignof (TREE_TYPE (TREE_TYPE (best)));    }  else    return c_alignof (TREE_TYPE (expr));}/* Return either DECL or its known constant value (if it has one).  */static treedecl_constant_value (decl)     tree decl;{  if (! TREE_PUBLIC (decl)      /* Don't change a variable array bound or initial value to a constant	 in a place where a variable is invalid.  */      && current_function_decl != 0      && ! pedantic      && ! TREE_THIS_VOLATILE (decl)      && TREE_READONLY (decl) && ! ITERATOR_P (decl)      && DECL_INITIAL (decl) != 0      && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK      /* This is invalid if initial value is not constant.	 If it has either a function call, a memory reference,	 or a variable, then re-evaluating it could give different results.  */      && TREE_CONSTANT (DECL_INITIAL (decl))      /* Check for cases where this is sub-optimal, even though valid.  */      && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR      && DECL_MODE (decl) != BLKmode)    return DECL_INITIAL (decl);  return decl;}/* Perform default promotions for C data used in expressions.   Arrays and functions are converted to pointers;   enumeral types or short or char, to int.   In addition, manifest constants symbols are replaced by their values.  */treedefault_conversion (exp)     tree exp;{  register tree type = TREE_TYPE (exp);  register enum tree_code code = TREE_CODE (type);  /* Constants can be used directly unless they're not loadable.  */  if (TREE_CODE (exp) == CONST_DECL)    exp = DECL_INITIAL (exp);  /* Replace a nonvolatile const static variable with its value unless     it is an array, in which case we must be sure that taking the     address of the array produces consistent results.  */  else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE)    {      exp = decl_constant_value (exp);      type = TREE_TYPE (exp);    }  /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as     an lvalue.  */  /* Do not use STRIP_NOPS here!  It will remove conversions from pointer     to integer and cause infinite recursion.  */  while (TREE_CODE (exp) == NON_LVALUE_EXPR	 || (TREE_CODE (exp) == NOP_EXPR	     && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))    exp = TREE_OPERAND (exp, 0);  /* Normally convert enums to int,     but convert wide enums to something wider.  */  if (code == ENUMERAL_TYPE)    {      type = type_for_size (MAX (TYPE_PRECISION (type),				 TYPE_PRECISION (integer_type_node)),			    ((flag_traditional			      || TYPE_PRECISION (type) >= TYPE_PRECISION (integer_type_node))			     && TREE_UNSIGNED (type)));      return convert (type, exp);    }  if (C_PROMOTING_INTEGER_TYPE_P (type))    {      /* Traditionally, unsignedness is preserved in default promotions.         Also preserve unsignedness if not really getting any wider.  */      if (TREE_UNSIGNED (type)	  && (flag_traditional	      || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))	return convert (unsigned_type_node, exp);      return convert (integer_type_node, exp);    }  if (flag_traditional && !flag_allow_single_precision      && TYPE_MAIN_VARIANT (type) == float_type_node)    return convert (double_type_node, exp);  if (code == VOID_TYPE)    {      error ("void value not ignored as it ought to be");      return error_mark_node;    }  if (code == FUNCTION_TYPE)    {      return build_unary_op (ADDR_EXPR, exp, 0);    }  if (code == ARRAY_TYPE)    {      register tree adr;      tree restype = TREE_TYPE (type);      tree ptrtype;      int constp = 0;      int volatilep = 0;      if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r'	  || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')	{	  constp = TREE_READONLY (exp);	  volatilep = TREE_THIS_VOLATILE (exp);	}      if (TYPE_READONLY (type) || TYPE_VOLATILE (type)	  || constp || volatilep)	restype = c_build_type_variant (restype,					TYPE_READONLY (type) || constp,					TYPE_VOLATILE (type) || volatilep);      if (TREE_CODE (exp) == INDIRECT_REF)	return convert (TYPE_POINTER_TO (restype),			TREE_OPERAND (exp, 0));      if (TREE_CODE (exp) == COMPOUND_EXPR)	{	  tree op1 = default_conversion (TREE_OPERAND (exp, 1));	  return build (COMPOUND_EXPR, TREE_TYPE (op1),			TREE_OPERAND (exp, 0), op1);	}      if (!lvalue_p (exp)	  && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))	{	  error ("invalid use of non-lvalue array");	  return error_mark_node;	}      ptrtype = build_pointer_type (restype);      if (TREE_CODE (exp) == VAR_DECL)	{	  /* ??? This is not really quite correct	     in that the type of the operand of ADDR_EXPR	     is not the target type of the type of the ADDR_EXPR itself.	     Question is, can this lossage be avoided?  */	  adr = build1 (ADDR_EXPR, ptrtype, exp);	  if (mark_addressable (exp) == 0)	    return error_mark_node;	  TREE_CONSTANT (adr) = staticp (exp);	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */	  return adr;	}      /* This way is better for a COMPONENT_REF since it can	 simplify the offset for a component.  */      adr = build_unary_op (ADDR_EXPR, exp, 1);      return convert (ptrtype, adr);    }  return exp;}/* Look up component name in the structure type definition.   If this component name is found indirectly within an anonymous union,   store in *INDIRECT the component which directly contains   that anonymous union.  Otherwise, set *INDIRECT to 0.  */     static treelookup_field (type, component, indirect)     tree type, component;     tree *indirect;{  tree field;  /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers     to the field elements.  Use a binary search on this array to quickly     find the element.  Otherwise, do a linear search.  TYPE_LANG_SPECIFIC     will always be set for structures which have many elements.  */  if (TYPE_LANG_SPECIFIC (type))    {      int bot, top, half;      tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0];      field = TYPE_FIELDS (type);      bot = 0;      top = TYPE_LANG_SPECIFIC (type)->len;      while (top - bot > 1)	{	  half = (top - bot + 1) >> 1;	  field = field_array[bot+half];	  if (DECL_NAME (field) == NULL_TREE)	    {	      /* Step through all anon unions in linear fashion.  */	      while (DECL_NAME (field_array[bot]) == NULL_TREE)		{		  tree anon, junk;		  field = field_array[bot++];		  anon = lookup_field (TREE_TYPE (field), component, &junk);		  if (anon != NULL_TREE)		    {		      *indirect = field;		      return anon;		    }		}	      /* Entire record is only anon unions.  */	      if (bot > top)		return NULL_TREE;	      /* Restart the binary search, with new lower bound.  */	      continue;	    }	  if (DECL_NAME (field) == component)	    break;	  if (DECL_NAME (field) < component)	    bot += half;	  else	    top = bot + half;	}      if (DECL_NAME (field_array[bot]) == component)	field = field_array[bot];      else if (DECL_NAME (field) != component)	field = 0;    }  else    {      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))	{	  if (DECL_NAME (field) == NULL_TREE)	    {	      tree junk;	      tree anon = lookup_field (TREE_TYPE (field), component, &junk);	      if (anon != NULL_TREE)		{		  *indirect = field;		  return anon;		}	    }	  if (DECL_NAME (field) == component)	    break;	}    }  *indirect = NULL_TREE;  return field;}/* Make an expression to refer to the COMPONENT field of   structure or union value DATUM.  COMPONENT is an IDENTIFIER_NODE.  */treebuild_component_ref (datum, component)     tree datum, component;{  register tree type = TREE_TYPE (datum);  register enum tree_code code = TREE_CODE (type);  register tree field = NULL;  register tree ref;  /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it     unless we are not to support things not strictly ANSI.  */  switch (TREE_CODE (datum))    {    case COMPOUND_EXPR:      {	tree value = build_component_ref (TREE_OPERAND (datum, 1), component);	return build (COMPOUND_EXPR, TREE_TYPE (value),		      TREE_OPERAND (datum, 0), value);      }    case COND_EXPR:      return build_conditional_expr	(TREE_OPERAND (datum, 0),	 build_component_ref (TREE_OPERAND (datum, 1), component),	 build_component_ref (TREE_OPERAND (datum, 2), component));    }

⌨️ 快捷键说明

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