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

📄 typeck.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
	    if (list_length (a1) < list_length (a2))	      attributes = a2, a2 = a1;	    for (; a2; a2 = TREE_CHAIN (a2))	      if (lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),				    attributes) == NULL_TREE)		{		  a1 = copy_node (a2);		  TREE_CHAIN (a1) = attributes;		  attributes = a1;		}	  }      }  }  /* Treat an enum type as the unsigned integer type of the same width.  */  if (TREE_CODE (t1) == ENUMERAL_TYPE)    t1 = type_for_size (TYPE_PRECISION (t1), 1);  if (TREE_CODE (t2) == ENUMERAL_TYPE)    t2 = type_for_size (TYPE_PRECISION (t2), 1);  if (TYPE_PTRMEMFUNC_P (t1))    t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);  if (TYPE_PTRMEMFUNC_P (t2))    t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);  code1 = TREE_CODE (t1);  code2 = TREE_CODE (t2);  /* If one type is complex, form the common type of the non-complex     components, then make that complex.  Use T1 or T2 if it is the     required type.  */  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)    {      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;      tree subtype = common_type (subtype1, subtype2);      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)	return build_type_attribute_variant (t1, attributes);      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)	return build_type_attribute_variant (t2, attributes);      else	return build_type_attribute_variant (build_complex_type (subtype),					     attributes);    }  switch (code1)    {    case INTEGER_TYPE:    case REAL_TYPE:      /* If only one is real, use it as the result.  */      if (code1 == REAL_TYPE && code2 != REAL_TYPE)	return build_type_attribute_variant (t1, attributes);      if (code2 == REAL_TYPE && code1 != REAL_TYPE)        return build_type_attribute_variant (t2, attributes);      /* Both real or both integers; use the one with greater precision.  */      if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))	return build_type_attribute_variant (t1, attributes);      else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))        return build_type_attribute_variant (t2, attributes);      /* Same precision.  Prefer longs to ints even when same size.  */        if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node	  || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)        return build_type_attribute_variant (long_unsigned_type_node,					     attributes);      if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node	  || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)	{	  /* But preserve unsignedness from the other type,	     since long cannot hold all the values of an unsigned int.  */	  if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))	     t1 = long_unsigned_type_node;	  else	     t1 = long_integer_type_node;	  return build_type_attribute_variant (t1, attributes);	}      if (TYPE_MAIN_VARIANT (t1) == long_double_type_node	  || TYPE_MAIN_VARIANT (t2) == long_double_type_node)	return build_type_attribute_variant (long_double_type_node,					     attributes);	        /* Otherwise prefer the unsigned one.  */      if (TREE_UNSIGNED (t1))	return build_type_attribute_variant (t1, attributes);      else	return build_type_attribute_variant (t2, attributes);    case POINTER_TYPE:    case REFERENCE_TYPE:      /* For two pointers, do this recursively on the target type,	 and combine the qualifiers of the two types' targets.  */      /* This code was turned off; I don't know why. 	 But ANSI C++ specifies doing this with the qualifiers. 	 So I turned it on again.  */      {	tree tt1 = TREE_TYPE (t1);	tree tt2 = TREE_TYPE (t2);	tree b1, b2;	int type_quals;	tree target;	if (TREE_CODE (tt1) == OFFSET_TYPE)	  {	    b1 = TYPE_OFFSET_BASETYPE (tt1);	    b2 = TYPE_OFFSET_BASETYPE (tt2);	    tt1 = TREE_TYPE (tt1);	    tt2 = TREE_TYPE (tt2);	  }	else	  b1 = b2 = NULL_TREE;	type_quals = (CP_TYPE_QUALS (tt1) | CP_TYPE_QUALS (tt2));	tt1 = TYPE_MAIN_VARIANT (tt1);	tt2 = TYPE_MAIN_VARIANT (tt2);	if (tt1 == tt2)	  target = tt1;	else if (b1)	  {	    compiler_error ("common_type called with uncommon member types");	    target = tt1;	  }	else if (tt1 == void_type_node || tt2 == void_type_node)	  target = void_type_node;	else if (tt1 == unknown_type_node)	  target = tt2;	else if (tt2 == unknown_type_node)	  target = tt1;	else	  target = common_type (tt1, tt2);	target = cp_build_qualified_type (target, type_quals);	if (b1)	  {	    if (same_type_p (b1, b2)		|| (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2)))	      target = build_offset_type (b2, target);	    else if (binfo_or_else (b2, b1))	      target = build_offset_type (b1, target);	  }	if (code1 == POINTER_TYPE)	  t1 = build_pointer_type (target);	else	  t1 = build_reference_type (target);	t1 = build_type_attribute_variant (t1, attributes);	if (TREE_CODE (target) == METHOD_TYPE)	  t1 = build_ptrmemfunc_type (t1);	return t1;      }    case ARRAY_TYPE:      {	tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));	/* Save space: see if the result is identical to one of the args.  */	if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))	  return build_type_attribute_variant (t1, attributes);	if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))	  return build_type_attribute_variant (t2, attributes);	/* Merge the element types, and have a size if either arg has one.  */	t1 = build_cplus_array_type	  (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));	return build_type_attribute_variant (t1, attributes);      }    case FUNCTION_TYPE:      /* Function types: prefer the one that specified arg types.	 If both do, merge the arg types.  Also merge the return types.  */      {	tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2));	tree p1 = TYPE_ARG_TYPES (t1);	tree p2 = TYPE_ARG_TYPES (t2);	tree rval, raises;	/* Save space: see if the result is identical to one of the args.  */	if (valtype == TREE_TYPE (t1) && ! p2)	  return build_type_attribute_variant (t1, attributes);	if (valtype == TREE_TYPE (t2) && ! p1)	  return build_type_attribute_variant (t2, attributes);	/* Simple way if one arg fails to specify argument types.  */	if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)	  {	    rval = build_function_type (valtype, p2);	    if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))	      rval = build_exception_variant (rval, raises);	    return build_type_attribute_variant (rval, attributes);	  }	raises = TYPE_RAISES_EXCEPTIONS (t1);	if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)	  {	    rval = build_function_type (valtype, p1);	    if (raises)	      rval = build_exception_variant (rval, raises);	    return build_type_attribute_variant (rval, attributes);	  }	rval = build_function_type (valtype, commonparms (p1, p2));	rval = build_exception_variant (rval, raises);	return build_type_attribute_variant (rval, attributes);      }    case RECORD_TYPE:    case UNION_TYPE:      t1 = TYPE_MAIN_VARIANT (t1);      t2 = TYPE_MAIN_VARIANT (t2);      if (DERIVED_FROM_P (t1, t2) && binfo_or_else (t1, t2))	return build_type_attribute_variant (t1, attributes);      else if (binfo_or_else (t2, t1))	return build_type_attribute_variant (t2, attributes);      else	{	  compiler_error ("common_type called with uncommon aggregate types");	  return error_mark_node;	}    case METHOD_TYPE:      if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2)))	{	  /* Get this value the long way, since TYPE_METHOD_BASETYPE	     is just the main variant of this.  */	  tree basetype;	  tree raises, t3;	  tree b1 = TYPE_OFFSET_BASETYPE (t1);	  tree b2 = TYPE_OFFSET_BASETYPE (t2);	  if (same_type_p (b1, b2)	      || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2)))	    basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2)));	  else	    {	      if (binfo_or_else (b2, b1) == NULL_TREE)		compiler_error ("common_type called with uncommon method types");	      basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t1)));	    }	  raises = TYPE_RAISES_EXCEPTIONS (t1);	  /* If this was a member function type, get back to the	     original type of type member function (i.e., without	     the class instance variable up front.  */	  t1 = build_function_type (TREE_TYPE (t1),				    TREE_CHAIN (TYPE_ARG_TYPES (t1)));	  t2 = build_function_type (TREE_TYPE (t2),				    TREE_CHAIN (TYPE_ARG_TYPES (t2)));	  t3 = common_type (t1, t2);	  t3 = build_cplus_method_type (basetype, TREE_TYPE (t3),					TYPE_ARG_TYPES (t3));	  t1 = build_exception_variant (t3, raises);	}      else        compiler_error ("common_type called with uncommon method types");      return build_type_attribute_variant (t1, attributes);    case OFFSET_TYPE:      /* Pointers to members should now be handled by the POINTER_TYPE	 case above.  */      my_friendly_abort (990325);    default:      return build_type_attribute_variant (t1, attributes);    }}/* Return 1 if TYPE1 and TYPE2 raise the same exceptions.  */intcompexcepttypes (t1, t2)     tree t1, t2;{  return TYPE_RAISES_EXCEPTIONS (t1) == TYPE_RAISES_EXCEPTIONS (t2);}/* Compare the array types T1 and T2, using CMP as the type comparison   function for the element types.  STRICT is as for comptypes.  */static intcomp_array_types (cmp, t1, t2, strict)     register int (*cmp) PROTO((tree, tree, int));     tree t1, t2;     int strict;{  tree d1;  tree d2;  if (t1 == t2)    return 1;  /* The type of the array elements must be the same.  */  if (!(TREE_TYPE (t1) == TREE_TYPE (t2)	|| (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2), 		   strict & ~COMPARE_REDECLARATION)))    return 0;  d1 = TYPE_DOMAIN (t1);  d2 = TYPE_DOMAIN (t2);  if (d1 == d2)    return 1;  /* If one of the arrays is dimensionless, and the other has a     dimension, they are of different types.  However, it is legal to     write:       extern int a[];       int a[3];     by [basic.link]:        declarations for an array object can specify       array types that differ by the presence or absence of a major       array bound (_dcl.array_).  */  if (!d1 || !d2)    return strict & COMPARE_REDECLARATION;  /* Check that the dimensions are the same.  */  return (cp_tree_equal (TYPE_MIN_VALUE (d1),			 TYPE_MIN_VALUE (d2))	  && cp_tree_equal (TYPE_MAX_VALUE (d1),			    TYPE_MAX_VALUE (d2)));}/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment   or various other operations.  STRICT is a bitwise-or of the   COMPARE_* flags.  */intcomptypes (type1, type2, strict)     tree type1, type2;     int strict;{  register tree t1 = type1;  register tree t2 = type2;  int attrval, val;  int orig_strict = strict;  /* The special exemption for redeclaring array types without an     array bound only applies at the top level:       extern int (*i)[];       int (*i)[8];     is not legal, for example.  */  strict &= ~COMPARE_REDECLARATION;  /* Suppress errors caused by previously reported errors */  if (t1 == t2)    return 1;  /* This should never happen.  */  my_friendly_assert (t1 != error_mark_node, 307);  if (t2 == error_mark_node)    return 0;  if (strict & COMPARE_RELAXED)    {      /* Treat an enum type as the unsigned integer type of the same width.  */      if (TREE_CODE (t1) == ENUMERAL_TYPE)	t1 = type_for_size (TYPE_PRECISION (t1), 1);      if (TREE_CODE (t2) == ENUMERAL_TYPE)	t2 = type_for_size (TYPE_PRECISION (t2), 1);      if (t1 == t2)	return 1;    }  if (TYPE_PTRMEMFUNC_P (t1))    t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);  if (TYPE_PTRMEMFUNC_P (t2))    t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);  /* Different classes of types can't be compatible.  */  if (TREE_CODE (t1) != TREE_CODE (t2))    return 0;  /* Qualifiers must match.  */  if (CP_TYPE_QUALS (t1) != CP_TYPE_QUALS (t2))    return 0;  if (strict == COMPARE_STRICT       && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))    return 0;  /* Allow for two different type nodes which have essentially the same     definition.  Note that we already checked for equality of the type     qualifiers (just above).  */  if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))    return 1;  /* ??? COMP_TYPE_ATTRIBUTES is currently useless for variables as each     attribute is its own main variant (`val' will remain 0).  */#ifndef COMP_TYPE_ATTRIBUTES#define COMP_TYPE_ATTRIBUTES(t1,t2)	1#endif  if (strict & COMPARE_NO_ATTRIBUTES)    attrval = 1;  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */  else if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2)))     return 0;  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */  val = 0;  switch (TREE_CODE (t1))    {    case TEMPLATE_TEMPLATE_PARM:      if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)	  || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))	return 0;      if (! comp_template_parms (DECL_TEMPLATE_PARMS (TYPE_NAME (t1)),				 DECL_TEMPLATE_PARMS (TYPE_NAME (t2))))	return 0;      if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t1) 	  && ! TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2))	return 1;      /* Don't check inheritance.  */      strict = COMPARE_STRICT;      /* fall through */    case RECORD_TYPE:    case UNION_TYPE:      if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)	  && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)	      || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM))	val = comp_template_args (TYPE_TI_ARGS (t1),				  TYPE_TI_ARGS (t2));    look_hard:      if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))	{	  val = 1;	  break;	}      if ((strict & COMPARE_RELAXED) && DERIVED_FROM_P (t2, t1))	{	  val = 1;	  break;	}      break;

⌨️ 快捷键说明

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