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

📄 typeck.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
	 they fail to match, unless STRICT is <= 0.  */      if (t1 == 0 || t2 == 0)	{	  if (strict > 0)	    return 0;	  if (strict < 0)	    return 1 + warn_contravariance;	  return ((t1 && TREE_PURPOSE (t1)) + warn_contravariance);	}      p1 = TREE_VALUE (t1);      p2 = TREE_VALUE (t2);      if (same_type_p (p1, p2))	continue;      if (pedantic)	return 0;      if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE)	  || (TREE_CODE (p1) == REFERENCE_TYPE	      && TREE_CODE (p2) == REFERENCE_TYPE))	{	  if (strict <= 0	      && (TYPE_MAIN_VARIANT (TREE_TYPE (p1))		  == TYPE_MAIN_VARIANT (TREE_TYPE (p2))))	    continue;	  /* The following is wrong for contravariance,	     but many programs depend on it.  */	  if (TREE_TYPE (p1) == void_type_node)	    continue;	  if (TREE_TYPE (p2) == void_type_node)	    {	      warn_contravariance = 1;	      continue;	    }	  if (IS_AGGR_TYPE (TREE_TYPE (p1))	      && !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (p1)),			       TYPE_MAIN_VARIANT (TREE_TYPE (p2))))	    return 0;	}      /* Note backwards order due to contravariance.  */      if (comp_target_types (p2, p1, 1) <= 0)	{	  if (comp_target_types (p1, p2, 1) > 0)	    {	      warn_contravariance = 1;	      continue;	    }	  if (strict != 0)	    return 0;	}    }  return warn_contravariance ? -1 : 1;}/* 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 an unsigned type the same as TYPE in other respects.   C++: must make these work for type variants as well.  */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;#if HOST_BITS_PER_WIDE_INT >= 64  if (type1 == intTI_type_node)    return unsigned_intTI_type_node;#endif  if (type1 == intDI_type_node)    return unsigned_intDI_type_node;  if (type1 == intSI_type_node)    return unsigned_intSI_type_node;  if (type1 == intHI_type_node)    return unsigned_intHI_type_node;  if (type1 == intQI_type_node)    return unsigned_intQI_type_node;  return signed_or_unsigned_type (1, 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;#if HOST_BITS_PER_WIDE_INT >= 64  if (type1 == unsigned_intTI_type_node)    return intTI_type_node;#endif  if (type1 == unsigned_intDI_type_node)    return intDI_type_node;  if (type1 == unsigned_intSI_type_node)    return intSI_type_node;  if (type1 == unsigned_intHI_type_node)    return intHI_type_node;  if (type1 == unsigned_intQI_type_node)    return intQI_type_node;  return signed_or_unsigned_type (0, 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 (! INTEGRAL_TYPE_P (type)      || TREE_UNSIGNED (type) == unsignedp)    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);  tree t;  if (processing_template_decl)    return build_min (SIZEOF_EXPR, sizetype, type);  if (code == FUNCTION_TYPE)    {      if (pedantic || warn_pointer_arith)	pedwarn ("ANSI C++ forbids taking the sizeof a function type");      return size_int (1);    }  if (code == METHOD_TYPE)    {      if (pedantic || warn_pointer_arith)	pedwarn ("ANSI C++ forbids taking the sizeof a method type");      return size_int (1);    }  if (code == VOID_TYPE)    {      if (pedantic || warn_pointer_arith)	pedwarn ("ANSI C++ forbids taking the sizeof a void type");      return size_int (1);    }  if (code == ERROR_MARK)    return size_int (1);  /* ARM $5.3.2: ``When applied to a reference, the result is the size of the     referenced object.'' */  if (code == REFERENCE_TYPE)    type = TREE_TYPE (type);  /* We couldn't find anything in the ARM or the draft standard that says,     one way or the other, if doing sizeof on something that doesn't have     an object associated with it is correct or incorrect.  For example, if     you declare `struct S { char str[16]; };', and in your program do     a `sizeof (S::str)', should we flag that as an error or should we give     the size of it?  Since it seems like a reasonable thing to do, we'll go     with giving the value.  */  if (code == OFFSET_TYPE)    type = TREE_TYPE (type);  /* @@ This also produces an error for a signature ref.        In that case we should be able to do better.  */  if (IS_SIGNATURE (type))    {      error ("`sizeof' applied to a signature type");      return size_int (0);    }  if (TYPE_SIZE (complete_type (type)) == 0)    {      cp_error ("`sizeof' applied to incomplete type `%T'", 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)));  t = convert (sizetype, t);  /* 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;}treeexpr_sizeof (e)     tree e;{  if (processing_template_decl)    return build_min (SIZEOF_EXPR, sizetype, e);  if (TREE_CODE (e) == COMPONENT_REF      && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))    error ("sizeof applied to a bit-field");  /* ANSI says arrays and functions are converted inside comma.     But we can't really convert them in build_compound_expr     because that would break commas in lvalues.     So do the conversion here if operand was a comma.  */  if (TREE_CODE (e) == COMPOUND_EXPR      && (TREE_CODE (TREE_TYPE (e)) == ARRAY_TYPE	  || TREE_CODE (TREE_TYPE (e)) == FUNCTION_TYPE))    e = default_conversion (e);  else if (is_overloaded_fn (e))    {      pedwarn ("ANSI C++ forbids taking the sizeof a function type");      return size_int (1);    }  else if (type_unknown_p (e))    {      incomplete_type_error (e, TREE_TYPE (e));      return size_int (1);    }  return c_sizeof (TREE_TYPE (e));}  treec_sizeof_nowarn (type)     tree type;{  enum tree_code code = TREE_CODE (type);  tree t;  if (code == FUNCTION_TYPE      || code == METHOD_TYPE      || code == VOID_TYPE      || code == ERROR_MARK)    return size_int (1);  if (code == REFERENCE_TYPE)    type = TREE_TYPE (type);  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)));  t = convert (sizetype, t);  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);  tree t;  if (processing_template_decl)    return build_min (ALIGNOF_EXPR, sizetype, type);  if (code == FUNCTION_TYPE || code == METHOD_TYPE)    return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);  if (code == VOID_TYPE || code == ERROR_MARK)    return size_int (1);  /* C++: this is really correct!  */  if (code == REFERENCE_TYPE)    type = TREE_TYPE (type);  /* @@ This also produces an error for a signature ref.        In that case we should be able to do better.  */  if (IS_SIGNATURE (type))    {      error ("`__alignof' applied to a signature type");      return size_int (1);    }  t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);  force_fit_type (t, 0);  return t;}/* Perform the array-to-pointer and function-to-pointer conversions   for EXP.     In addition, references are converted to rvalues and manifest   constants are replaced by their values.  */treedecay_conversion (exp)     tree exp;{  register tree type;  register enum tree_code code;  if (TREE_CODE (exp) == OFFSET_REF)    exp = resolve_offset_ref (exp);  type = TREE_TYPE (exp);  code = TREE_CODE (type);  if (code == REFERENCE_TYPE)    {      exp = convert_from_reference (exp);      type = TREE_TYPE (exp);      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.  We     don't do this for arrays, though; we want the address of the     first element of the array, not the address of the first element     of its initializing constant.  We *do* replace variables that the     user isn't really supposed to know about; this is a hack to deal     with __PRETTY_FUNCTION__ and the like.  */  else if (TREE_READONLY_DECL_P (exp)	   && (code != ARRAY_TYPE 	       || (TREE_CODE (exp) == VAR_DECL && DECL_IGNORED_P (exp))))    {      exp = decl_constant_value (exp);      type = TREE_TYPE (exp);    }  /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.     Leave such NOP_EXPRs, since RHS is being used in non-lvalue context.  */  if (code == VOID_TYPE)    {      error ("void value not ignored as it ought to be");      return error_mark_node;    }  if (code == METHOD_TYPE)    my_friendly_abort (990506);  if (code == FUNCTION_TYPE || is_overloaded_fn (exp))    return build_unary_op (ADDR_EXPR, exp, 0);  if (code == ARRAY_TYPE)    {      register tree adr;      tree ptrtype;      if (TREE_CODE (exp) == INDIRECT_REF)	{	  /* Stripping away the INDIRECT_REF is not the right	     thing to do for references...  */	  tree inner = TREE_OPERAND (exp, 0);	  if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE)	    {	      inner = build1 (CONVERT_EXPR,			      build_pointer_type (TREE_TYPE						  (TREE_TYPE (inner))),			      inner);	      TREE_CONSTANT (inner) = TREE_CONSTANT (TREE_OPERAND (inner, 0));	    }	  return cp_convert (build_pointer_type (TREE_TYPE (type)), inner);	}      if (TREE_CODE (exp) == COMPOUND_EXPR)	{	  tree op1 = decay_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 (TREE_TYPE (type));      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 cp_convert (ptrtype, adr);    }  return exp;}treedefault_conversion (exp)

⌨️ 快捷键说明

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