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

📄 c-typeck.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
      }    case RECORD_TYPE:      return maybe_objc_comptypes (t1, t2);    }  return 0;}/* Return 1 if TTL and TTR are pointers to types that are equivalent,   ignoring their qualifiers.  */static intcomp_target_types (ttl, ttr)     tree ttl, ttr;{  int val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),		       TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));  if (val == 2 && pedantic)    pedwarn ("types are not quite compatible");  return val;}/* Subroutines of `comptypes'.  *//* Return 1 if two function types F1 and F2 are compatible.   If either type specifies no argument types,   the other must specify a fixed number of self-promoting arg types.   Otherwise, if one type specifies only the number of arguments,    the other must specify that number of self-promoting arg types.   Otherwise, the argument types must match.  */static intfunction_types_compatible_p (f1, f2)     tree f1, f2;{  tree args1, args2;  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */  int val = 1;  int val1;  if (!(TREE_TYPE (f1) == TREE_TYPE (f2)	|| (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2)))))    return 0;  args1 = TYPE_ARG_TYPES (f1);  args2 = TYPE_ARG_TYPES (f2);  /* An unspecified parmlist matches any specified parmlist     whose argument types don't need default promotions.  */  if (args1 == 0)    {      if (!self_promoting_args_p (args2))	return 0;      /* If one of these types comes from a non-prototype fn definition,	 compare that with the other type's arglist.	 If they don't match, ask for a warning (but no error).  */      if (TYPE_ACTUAL_ARG_TYPES (f1)	  && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1)))	val = 2;      return val;    }  if (args2 == 0)    {      if (!self_promoting_args_p (args1))	return 0;      if (TYPE_ACTUAL_ARG_TYPES (f2)	  && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2)))	val = 2;      return val;    }  /* Both types have argument lists: compare them and propagate results.  */  val1 = type_lists_compatible_p (args1, args2);  return val1 != 1 ? val1 : val;}/* Check two lists of types for compatibility,   returning 0 for incompatible, 1 for compatible,   or 2 for compatible with warning.  */static inttype_lists_compatible_p (args1, args2)     tree args1, args2;{  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */  int val = 1;  int newval;  while (1)    {      if (args1 == 0 && args2 == 0)	return val;      /* If one list is shorter than the other,	 they fail to match.  */      if (args1 == 0 || args2 == 0)	return 0;      /* A null pointer instead of a type	 means there is supposed to be an argument	 but nothing is specified about what type it has.	 So match anything that self-promotes.  */      if (TREE_VALUE (args1) == 0)	{	  if (! self_promoting_type_p (TREE_VALUE (args2)))	    return 0;	}      else if (TREE_VALUE (args2) == 0)	{	  if (! self_promoting_type_p (TREE_VALUE (args1)))	    return 0;	}      else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2))))	{	  /* Allow  wait (union {union wait *u; int *i} *)	     and  wait (union wait *)  to be compatible.  */	  if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE	      && TYPE_NAME (TREE_VALUE (args1)) == 0	      && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST	      && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)),				     TYPE_SIZE (TREE_VALUE (args2))))	    {	      tree memb;	      for (memb = TYPE_FIELDS (TREE_VALUE (args1));		   memb; memb = TREE_CHAIN (memb))		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))		  break;	      if (memb == 0)		return 0;	    }	  else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE		   && TYPE_NAME (TREE_VALUE (args2)) == 0		   && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST		   && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)),					  TYPE_SIZE (TREE_VALUE (args1))))	    {	      tree memb;	      for (memb = TYPE_FIELDS (TREE_VALUE (args2));		   memb; memb = TREE_CHAIN (memb))		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))		  break;	      if (memb == 0)		return 0;	    }	  else	    return 0;	}      /* comptypes said ok, but record if it said to warn.  */      if (newval > val)	val = newval;      args1 = TREE_CHAIN (args1);      args2 = TREE_CHAIN (args2);    }}/* Return 1 if PARMS specifies a fixed number of parameters   and none of their types is affected by default promotions.  */intself_promoting_args_p (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 == 0)	return 0;      if (TYPE_MAIN_VARIANT (type) == float_type_node)	return 0;      if (C_PROMOTING_INTEGER_TYPE_P (type))	return 0;    }  return 1;}/* Return 1 if TYPE is not affected by default promotions.  */static intself_promoting_type_p (type)     tree type;{  if (TYPE_MAIN_VARIANT (type) == float_type_node)    return 0;  if (C_PROMOTING_INTEGER_TYPE_P (type))    return 0;  return 1;}/* Return an unsigned type the same as TYPE in other respects.  */treeunsigned_type (type)     tree type;{  tree type1 = TYPE_MAIN_VARIANT (type);  if (type1 == signed_char_type_node || type1 == char_type_node)    return unsigned_char_type_node;  if (type1 == integer_type_node)    return unsigned_type_node;  if (type1 == short_integer_type_node)    return short_unsigned_type_node;  if (type1 == long_integer_type_node)    return long_unsigned_type_node;  if (type1 == 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;{  tree type1 = TYPE_MAIN_VARIANT (type);  if (type1 == unsigned_char_type_node || type1 == char_type_node)    return signed_char_type_node;  if (type1 == unsigned_type_node)    return integer_type_node;  if (type1 == short_unsigned_type_node)    return short_integer_type_node;  if (type1 == long_unsigned_type_node)    return long_integer_type_node;  if (type1 == 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;}/* Compute the value of the `sizeof' operator.  */treec_sizeof (type)     tree type;{  enum tree_code code = TREE_CODE (type);  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.  */  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 		     size_int (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      || 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.  */  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 		     size_int (TYPE_PRECISION (char_type_node)));}/* Compute the size to increment a pointer by.  */treec_size_in_bytes (type)     tree type;{  enum tree_code code = TREE_CODE (type);  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.  */  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 		     size_int (BITS_PER_UNIT));}/* 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)      && 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);

⌨️ 快捷键说明

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