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

📄 cp-type2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	       - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))	       + 1);      else	len = -1;  /* Take as many as there are */      for (i = 0; (len < 0 || i < len) && tail != 0; i++)	{	  register tree next1;	  if (TREE_VALUE (tail) != 0)	    {	      tree tail1 = tail;	      next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)),				   TREE_VALUE (tail), &tail1);	      my_friendly_assert (tail1 == 0				  || TREE_CODE (tail1) == TREE_LIST, 319);	      if (tail == tail1 && len < 0)		{		  error ("non-empty initializer for array of empty elements");		  /* Just ignore what we were supposed to use.  */		  tail1 = 0;		}	      tail = tail1;	    }	  else	    {	      next1 = error_mark_node;	      tail = TREE_CHAIN (tail);	    }	  if (next1 == error_mark_node)	    erred = 1;	  else if (!TREE_CONSTANT (next1))	    allconstant = 0;	  else if (! initializer_constant_valid_p (next1))	    allsimple = 0;	  members = tree_cons (NULL_TREE, next1, members);	}    }  if (TREE_CODE (type) == RECORD_TYPE && init != empty_init_node)    {      register tree field;      if (tail)	{	  if (TYPE_USES_VIRTUAL_BASECLASSES (type))	    {	      sorry ("initializer list for object of class with virtual baseclasses");	      return error_mark_node;	    }	  if (TYPE_BINFO_BASETYPES (type))	    {	      sorry ("initializer list for object of class with baseclasses");	      return error_mark_node;	    }	  if (TYPE_VIRTUAL_P (type))	    {	      sorry ("initializer list for object using virtual functions");	      return error_mark_node;	    }	}      for (field = TYPE_FIELDS (type); field && tail;	   field = TREE_CHAIN (field))	{	  register tree next1;	  if (! DECL_NAME (field))	    {	      members = tree_cons (field, integer_zero_node, members);	      continue;	    }	  if (TREE_CODE (field) == CONST_DECL || TREE_CODE (field) == TYPE_DECL)	    continue;	  if (TREE_CODE (field) == VAR_DECL && !TREE_STATIC (field))	    continue;	  if (TREE_VALUE (tail) != 0)	    {	      tree tail1 = tail;	      next1 = digest_init (TREE_TYPE (field),				   TREE_VALUE (tail), &tail1);	      my_friendly_assert (tail1 == 0				  || TREE_CODE (tail1) == TREE_LIST, 320);	      if (TREE_CODE (field) == VAR_DECL		  && ! global_bindings_p ())		warning_with_decl (field, "initialization of static member `%s'");	      tail = tail1;	    }	  else	    {	      next1 = error_mark_node;	      tail = TREE_CHAIN (tail);	    }	  if (next1 == error_mark_node)	    erred = 1;	  else if (!TREE_CONSTANT (next1))	    allconstant = 0;	  else if (! initializer_constant_valid_p (next1))	    allsimple = 0;	  members = tree_cons (field, next1, members);	}      for (; field; field = TREE_CHAIN (field))	{	  if (TREE_CODE (field) != FIELD_DECL)	    continue;	  /* Does this field have a default initialization?  */	  if (DECL_INITIAL (field))	    {	      register tree next1 = DECL_INITIAL (field);	      if (TREE_CODE (next1) == ERROR_MARK)		erred = 1;	      else if (!TREE_CONSTANT (next1))		allconstant = 0;	      else if (! initializer_constant_valid_p (next1))		allsimple = 0;	      members = tree_cons (field, next1, members);	    }	  else if (TREE_READONLY (field))	    error ("uninitialized const member `%s'",		   IDENTIFIER_POINTER (DECL_NAME (field)));	  else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field))		   && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))	    error ("member `%s' with uninitialized const fields",		   IDENTIFIER_POINTER (DECL_NAME (field)));	  else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)	    error ("member `%s' is uninitialized reference",		   IDENTIFIER_POINTER (DECL_NAME (field)));	}    }  /* If arguments were specified as a list, just remove the ones we used.  */  if (elts)    *elts = tail;  /* If arguments were specified as a constructor,     complain unless we used all the elements of the constructor.  */  else if (tail)    warning ("excess elements in aggregate initializer");  if (erred)    return error_mark_node;  result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members));  if (init)    TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init);  if (allconstant) TREE_CONSTANT (result) = 1;  if (allconstant && allsimple) TREE_STATIC (result) = 1;  return result;}/* Given a structure or union value DATUM, construct and return   the structure or union component which results from narrowing   that value by the types specified in TYPES.  For example, given the   hierarchy   class L { int ii; };   class A : L { ... };   class B : L { ... };   class C : A, B { ... };   and the declaration   C x;   then the expression   x::C::A::L::ii refers to the ii member of the L part of   of A part of the C object named by X.  In this case,   DATUM would be x, and TYPES would be a SCOPE_REF consisting of	SCOPE_REF		SCOPE_REF			C	A		L   The last entry in the SCOPE_REF is always an IDENTIFIER_NODE.*/treebuild_scoped_ref (datum, types)     tree datum;     tree types;{  tree orig_ref, ref;  tree type = TREE_TYPE (datum);  if (datum == error_mark_node)    return error_mark_node;  type = TYPE_MAIN_VARIANT (type);  if (TREE_CODE (types) == SCOPE_REF)    {      /* We have some work to do.  */      struct type_chain { tree type; struct type_chain *next; } *chain = 0, *head = 0, scratch;      orig_ref = ref = build_unary_op (ADDR_EXPR, datum, 0);      while (TREE_CODE (types) == SCOPE_REF)	{	  tree t = TREE_OPERAND (types, 1);	  if (is_aggr_typedef (t, 1))	    {	      head = (struct type_chain *)alloca (sizeof (struct type_chain));	      head->type = IDENTIFIER_TYPE_VALUE (t);	      head->next = chain;	      chain = head;	      types = TREE_OPERAND (types, 0);	    }	  else return error_mark_node;	}      if (! is_aggr_typedef (types, 1))	return error_mark_node;      head = &scratch;      head->type = IDENTIFIER_TYPE_VALUE (types);      head->next = chain;      chain = head;      while (chain)	{	  tree binfo = chain->type;	  type = TREE_TYPE (TREE_TYPE (ref));	  if (binfo != TYPE_BINFO (type))	    {	      binfo = get_binfo (binfo, type, 1);	      if (binfo == error_mark_node)		return error_mark_node;	      if (binfo == 0)		return error_not_base_type (TYPE_NAME_STRING (chain->type), TYPE_NAME_STRING (type));	      ref = convert_pointer_to (binfo, ref);	    }	  chain = chain->next;	}      return build_indirect_ref (ref, "(compiler error in build_scoped_ref)");    }  /* This is an easy conversion.  */  if (is_aggr_typedef (types, 1))    {      tree binfo = TYPE_BINFO (IDENTIFIER_TYPE_VALUE (types));      if (binfo != TYPE_BINFO (type))	{	  binfo = get_binfo (binfo, type, 1);	  if (binfo == error_mark_node)	    return error_mark_node;	  if (binfo == 0)	    return error_not_base_type (IDENTIFIER_TYPE_VALUE (types), type);	}      switch (TREE_CODE (datum))	{	case NOP_EXPR:	case CONVERT_EXPR:	case FLOAT_EXPR:	case FIX_TRUNC_EXPR:	case FIX_FLOOR_EXPR:	case FIX_ROUND_EXPR:	case FIX_CEIL_EXPR:	  ref = convert_pointer_to (binfo,				    build_unary_op (ADDR_EXPR, TREE_OPERAND (datum, 0), 0));	  break;	default:	  ref = convert_pointer_to (binfo,				    build_unary_op (ADDR_EXPR, datum, 0));	}      return build_indirect_ref (ref, "(compiler error in build_scoped_ref)");    }  return error_mark_node;}/* Build a reference to an object specified by the C++ `->' operator.   Usually this just involves dereferencing the object, but if the   `->' operator is overloaded, then such overloads must be   performed until an object which does not have the `->' operator   overloaded is found.  An error is reported when circular pointer   delegation is detected.  */treebuild_x_arrow (datum)     tree datum;{  tree types_memoized = NULL_TREE;  register tree rval = datum;  tree type = TREE_TYPE (rval);  tree last_rval;  if (type == error_mark_node)    return error_mark_node;  if (TREE_CODE (type) == REFERENCE_TYPE)    {      rval = convert_from_reference (rval);      type = TREE_TYPE (rval);    }  if (IS_AGGR_TYPE (type) && TYPE_OVERLOADS_ARROW (type))    {      while (rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval))	{	  if (rval == error_mark_node)	    return error_mark_node;	  if (value_member (TREE_TYPE (rval), types_memoized))	    {	      error ("circular pointer delegation detected");	      return error_mark_node;	    }	  else	    {	      types_memoized = tree_cons (NULL_TREE, TREE_TYPE (rval),					  types_memoized);	    }	  last_rval = rval;	}           if (TREE_CODE (TREE_TYPE (last_rval)) == REFERENCE_TYPE)	last_rval = convert_from_reference (last_rval);    }  else    last_rval = default_conversion (rval); more:  if (TREE_CODE (TREE_TYPE (last_rval)) == POINTER_TYPE)    return build_indirect_ref (last_rval, 0);  if (TREE_CODE (TREE_TYPE (last_rval)) == OFFSET_TYPE)    {      if (TREE_CODE (last_rval) == OFFSET_REF	  && TREE_STATIC (TREE_OPERAND (last_rval, 1)))	{	  last_rval = TREE_OPERAND (last_rval, 1);	  if (TREE_CODE (TREE_TYPE (last_rval)) == REFERENCE_TYPE)	    last_rval = convert_from_reference (last_rval);	  goto more;	}      compiler_error ("invalid member type in build_x_arrow");      return error_mark_node;    }  if (types_memoized)    error ("result of `operator->()' yields non-pointer result");  else    error ("base operand of `->' is not a pointer");  return error_mark_node;}/* Make an expression to refer to the COMPONENT field of   structure or union value DATUM.  COMPONENT is an arbitrary   expression.  DATUM has already been checked out to be of   aggregate type.   For C++, COMPONENT may be a TREE_LIST.  This happens when we must   return an object of member type to a method of the current class,   but there is not yet enough typing information to know which one.   As a special case, if there is only one method by that name,   it is returned.  Otherwise we return an expression which other   routines will have to know how to deal with later.  */treebuild_m_component_ref (datum, component)     tree datum, component;{  tree type = TREE_TYPE (component);  tree objtype = TREE_TYPE (datum);  if (datum == error_mark_node || component == error_mark_node)    return error_mark_node;  if (TREE_CODE (type) != OFFSET_TYPE && TREE_CODE (type) != METHOD_TYPE)    {      error ("non-member type composed with object");      return error_mark_node;    }  if (TREE_CODE (objtype) == REFERENCE_TYPE)    objtype = TREE_TYPE (objtype);  if (! comptypes (TYPE_METHOD_BASETYPE (type), objtype, 0))    {      error ("member type `%s::' incompatible with object type `%s'",	     TYPE_NAME_STRING (TYPE_METHOD_BASETYPE (type)),	     TYPE_NAME_STRING (objtype));      return error_mark_node;    }  return build (OFFSET_REF, TREE_TYPE (TREE_TYPE (component)), datum, component);}/* Return a tree node for the expression TYPENAME '(' PARMS ')'.   Because we cannot tell whether this construct is really

⌨️ 快捷键说明

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