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

📄 c-typeck.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (t1 == 0 && t2 == 0)	return 1;      /* If one parmlist is shorter than the other,	 they fail to match.  */      if (t1 == 0 || t2 == 0)	return 0;      if (! comptypes (TREE_VALUE (t1), TREE_VALUE (t2)))	return 0;      t1 = TREE_CHAIN (t1);      t2 = TREE_CHAIN (t2);    }}/* Return 1 if PARMS specifies a fixed number of parameters   and none of their types is affected by default promotions.  */intcompparms1 (parms)     tree parms;{  register tree t;  for (t = parms; t; t = TREE_CHAIN (t))    {      register tree type = TREE_VALUE (t);      if (TREE_CHAIN (t) == 0 && type != void_type_node)	return 0;      if (type == float_type_node)	return 0;      if (TREE_CODE (type) == INTEGER_TYPE	  && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))	return 0;    }  return 1;}/* Return an unsigned type the same as TYPE in other respects.  */treeunsigned_type (type)     tree type;{  if (type == signed_char_type_node || type == char_type_node)    return unsigned_char_type_node;  if (type == integer_type_node)    return unsigned_type_node;  if (type == short_integer_type_node)    return short_unsigned_type_node;  if (type == long_integer_type_node)    return long_unsigned_type_node;  if (type == long_long_integer_type_node)    return long_long_unsigned_type_node;  return type;}/* Return a signed type the same as TYPE in other respects.  */treesigned_type (type)     tree type;{  if (type == unsigned_char_type_node || type == char_type_node)    return signed_char_type_node;  if (type == unsigned_type_node)    return integer_type_node;  if (type == short_unsigned_type_node)    return short_integer_type_node;  if (type == long_unsigned_type_node)    return long_integer_type_node;  if (type == long_long_unsigned_type_node)    return long_long_integer_type_node;  return type;}/* Return a type the same as TYPE except unsigned or   signed according to UNSIGNEDP.  */treesigned_or_unsigned_type (unsignedp, type)     int unsignedp;     tree type;{  if (TREE_CODE (type) != INTEGER_TYPE)    return type;  if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))    return unsignedp ? unsigned_char_type_node : signed_char_type_node;  if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))     return unsignedp ? unsigned_type_node : integer_type_node;  if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))     return unsignedp ? short_unsigned_type_node : short_integer_type_node;  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))     return unsignedp ? long_unsigned_type_node : long_integer_type_node;  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))     return (unsignedp ? long_long_unsigned_type_node	    : long_long_integer_type_node);  return type;}/* Return an integer type with BITS bits of precision,   that is unsigned if UNSIGNEDP is nonzero, otherwise signed.  */treetype_for_size (bits, unsignedp)     int bits;     int unsignedp;{  if (bits <= TYPE_PRECISION (signed_char_type_node))    return unsignedp ? unsigned_char_type_node : signed_char_type_node;  if (bits <= TYPE_PRECISION (short_integer_type_node))    return unsignedp ? short_unsigned_type_node : short_integer_type_node;  if (bits <= TYPE_PRECISION (integer_type_node))    return unsignedp ? unsigned_type_node : integer_type_node;  if (bits <= TYPE_PRECISION (long_integer_type_node))    return unsignedp ? long_unsigned_type_node : long_integer_type_node;  if (bits <= TYPE_PRECISION (long_long_integer_type_node))    return (unsignedp ? long_long_unsigned_type_node	    : long_long_integer_type_node);  return 0;}treeget_floating_type (mode)     enum machine_mode mode;{  if (mode == TYPE_MODE (float_type_node))    return float_type_node;  if (mode == TYPE_MODE (double_type_node))    return double_type_node;  if (mode == TYPE_MODE (long_double_type_node))    return long_double_type_node;  abort ();}treec_sizeof (type)     tree type;{  enum tree_code code = TREE_CODE (type);  if (code == FUNCTION_TYPE)    {      if (pedantic || warn_pointer_arith)	warning ("sizeof applied to a function type");      return build_int (1);    }  if (code == VOID_TYPE)    {      if (pedantic || warn_pointer_arith)	warning ("sizeof applied to a void type");      return build_int (1);    }  /* Convert in case a char is more than one unit.  */  return convert_units (size_in_bytes (type), BITS_PER_UNIT,			TYPE_PRECISION (char_type_node));}treec_sizeof_nowarn (type)     tree type;{  enum tree_code code = TREE_CODE (type);  if (code == FUNCTION_TYPE      || code == VOID_TYPE)    return build_int (1);  /* Convert in case a char is more than one unit.  */  return convert_units (size_in_bytes (type), BITS_PER_UNIT,			TYPE_PRECISION (char_type_node));}/* 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 build_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);  if (code == VOID_TYPE)    return build_int (1);  return build_int (TYPE_ALIGN (type) / BITS_PER_UNIT);}/* 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)      && 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_LITERAL (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 dt = TREE_TYPE (exp);  register enum tree_code form = TREE_CODE (dt);  if (TREE_CODE (exp) == CONST_DECL)    exp = DECL_INITIAL (exp);  /* Replace a nonvolatile const static variable with its value.  */  else if (optimize	   && TREE_CODE (exp) == VAR_DECL	   && TREE_READONLY (exp))    exp = decl_constant_value (exp);  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.     Strip such NOP_EXPRs, since EXP is being used in non-lvalue context.  */  if (TREE_CODE (exp) == NOP_EXPR      && TREE_TYPE (exp) == TREE_TYPE (TREE_OPERAND (exp, 0)))    exp = TREE_OPERAND (exp, 0);  if (form == ENUMERAL_TYPE      || (form == INTEGER_TYPE	  && (TYPE_PRECISION (dt)	      < TYPE_PRECISION (integer_type_node))))    {      /* Traditionally, unsignedness is preserved in default promotions.  */      if (flag_traditional && TREE_UNSIGNED (dt))	return convert (unsigned_type_node, exp);      return convert (integer_type_node, exp);    }  if (flag_traditional && dt == float_type_node)    return convert (double_type_node, exp);  if (form == VOID_TYPE)    {      error ("void value not ignored as it ought to be");      return error_mark_node;    }  if (form == FUNCTION_TYPE)    {      return build_unary_op (ADDR_EXPR, exp, 0);    }  if (form == ARRAY_TYPE)    {      register tree adr;      tree restype = TREE_TYPE (dt);      tree ptrtype;      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;	}      if (TREE_READONLY (exp) || TREE_THIS_VOLATILE (exp))	restype = c_build_type_variant (restype, TREE_READONLY (exp),					TREE_THIS_VOLATILE (exp));      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 = build (ADDR_EXPR, ptrtype, exp);	  if (mark_addressable (exp) == 0)	    return error_mark_node;	  TREE_LITERAL (adr) = staticp (exp);	  TREE_VOLATILE (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;}/* 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 basename = datum;  register tree basetype = TREE_TYPE (basename);  register enum tree_code form = TREE_CODE (basetype);  register tree field = NULL;  register tree ref;  /* First, see if there is a field or component with name COMPONENT. */  if (form == RECORD_TYPE || form == UNION_TYPE)    {      if (TYPE_SIZE (basetype) == 0)	{	  incomplete_type_error (0, basetype);	  return error_mark_node;	}      /* Look up component name in the structure type definition.  */      for (field = TYPE_FIELDS (basetype); field; field = TREE_CHAIN (field))	{	  if (DECL_NAME (field) == component)	    break;	}      if (!field)	{	  error (form == RECORD_TYPE		 ? "structure has no member named `%s'"		 : "union has no member named `%s'",		 IDENTIFIER_POINTER (component));	  return error_mark_node;	}      if (TREE_TYPE (field) == error_mark_node)	return error_mark_node;      ref = build (COMPONENT_REF, TREE_TYPE (field), basename, field);      if (TREE_READONLY (basename) || TREE_READONLY (field))	TREE_READONLY (ref) = 1;      if (TREE_THIS_VOLATILE (basename) || TREE_VOLATILE (field))	TREE_THIS_VOLATILE (ref) = 1;      return ref;    }  else if (form != ERROR_MARK)    error ("request for member `%s' in something not a structure or union",	    IDENTIFIER_POINTER (component));  return error_mark_node;}/* Given an expression PTR for a pointer, return an expression   for the value pointed to.   ERRORSTRING is the name of the operator to appear in error messages.  */treebuild_indirect_ref (ptr, errorstring)     tree ptr;     char *errorstring;{  register tree pointer = default_conversion (ptr);  register tree dt = TREE_TYPE (pointer);  if (TREE_CODE (dt) == POINTER_TYPE)    if (TREE_CODE (pointer) == ADDR_EXPR	&& (TREE_TYPE (TREE_OPERAND (pointer, 0))	    == TREE_TYPE (dt)))      return TREE_OPERAND (pointer, 0);    else      {	tree t = TREE_TYPE (dt);	register tree ref = build (INDIRECT_REF,				   TYPE_MAIN_VARIANT (t), pointer);	if (TREE_CODE (t) == VOID_TYPE	    || (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE))	  {	    error ("dereferencing pointer to incomplete type");	    return error_mark_node;	  }	TREE_READONLY (ref) = TREE_READONLY (t);	TREE_VOLATILE (ref) = TREE_VOLATILE (t) || TREE_VOLATILE (pointer);	TREE_THIS_VOLATILE (ref) = TREE_VOLATILE (t);	return ref;      }  else if (TREE_CODE (pointer) != ERROR_MARK)    error ("invalid type argument of `%s'", errorstring);  return error_mark_node;}/* This handles expressions of the form "a[i]", which denotes   an array reference.   This is logically equivalent in C to *(a+i), but we may do it differently.   If A is a variable or a member, we generate a primitive ARRAY_REF.   This avoids forcing the array out of registers, and can work on   arrays that are not lvalues (for example, members of structures returned   by functions).  */treebuild_array_ref (array, index)     tree array, index;{

⌨️ 快捷键说明

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