FreeBSD/contrib/gcc/cp/decl.c
/* Create the binfo hierarchy for REF with (possibly NULL) base list
   BASE_LIST.  For each element on BASE_LIST the TREE_PURPOSE is an
   access_* node, and the TREE_VALUE is the type of the base-class.
   Non-NULL TREE_TYPE indicates virtual inheritance.  
 
   Returns true if the binfo heirarchy was successfully created,
   false if an error was detected. */
Create the binfo hierarchy for REF with (possibly NULL) base list
BASE_LIST.  For each element on BASE_LIST the TREE_PURPOSE is an
access_* node, and the TREE_VALUE is the type of the base-class.
Non-NULL TREE_TYPE indicates virtual inheritance.

Returns true if the binfo heirarchy was successfully created,
false if an error was detected.
Create the binfo hierarchy for REF with ( possibly NULL ) base list BASE_LIST . For each element on BASE_LIST the TREE_PURPOSE is an access_ * node and the TREE_VALUE is the type of the base - class . Non - NULL TREE_TYPE indicates virtual inheritance . Returns true if the binfo heirarchy was successfully created false if an error was detected .
bool
xref_basetypes (tree ref, tree base_list)
{
  tree *basep;
  tree binfo, base_binfo;
  unsigned max_vbases = 0; 
  unsigned max_bases = 0;  
  int i;
  tree default_access;
  tree igo_prev; 
  if (ref == error_mark_node)
    return false;
  default_access = (TREE_CODE (ref) == RECORD_TYPE
		    && CLASSTYPE_DECLARED_CLASS (ref)
		    ? access_private_node : access_public_node);
  basep = &base_list;
  while (*basep)
    {
      tree basetype = TREE_VALUE (*basep);
      if (!(processing_template_decl && uses_template_parms (basetype))
	  && !complete_type_or_else (basetype, NULL))
	*basep = TREE_CHAIN (*basep);
      else
	{
	  max_bases++;
	  if (TREE_TYPE (*basep))
	    max_vbases++;
	  if (CLASS_TYPE_P (basetype))
	    max_vbases += VEC_length (tree, CLASSTYPE_VBASECLASSES (basetype));
	  basep = &TREE_CHAIN (*basep);
	}
    }
  TYPE_MARKED_P (ref) = 1;
  gcc_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref));
  gcc_assert (TYPE_MAIN_VARIANT (ref) == ref);
  binfo = make_tree_binfo (max_bases);
  TYPE_BINFO (ref) = binfo;
  BINFO_OFFSET (binfo) = size_zero_node;
  BINFO_TYPE (binfo) = ref;
  if (max_bases)
    {
      BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, max_bases);
      CLASSTYPE_NON_AGGREGATE (ref) = 1;
      if (TREE_CODE (ref) == UNION_TYPE)
        {
	  error ("derived union %qT invalid", ref);
          return false;
        }
    }
  if (max_bases > 1)
    {
      if (TYPE_FOR_JAVA (ref))
        {
	  error ("Java class %qT cannot have multiple bases", ref);
          return false;
        }
    }
  if (max_vbases)
    {
      CLASSTYPE_VBASECLASSES (ref) = VEC_alloc (tree, gc, max_vbases);
      if (TYPE_FOR_JAVA (ref))
        {
	  error ("Java class %qT cannot have virtual bases", ref);
          return false;
        }
    }
  for (igo_prev = binfo; base_list; base_list = TREE_CHAIN (base_list))
    {
      tree access = TREE_PURPOSE (base_list);
      int via_virtual = TREE_TYPE (base_list) != NULL_TREE;
      tree basetype = TREE_VALUE (base_list);
      if (access == access_default_node)
	access = default_access;
      if (TREE_CODE (basetype) == TYPE_DECL)
	basetype = TREE_TYPE (basetype);
      if (TREE_CODE (basetype) != RECORD_TYPE
	  && TREE_CODE (basetype) != TYPENAME_TYPE
	  && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
	  && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM)
	{
	  error ("base type %qT fails to be a struct or class type",
		 basetype);
	  return false;
	}
      if (TYPE_FOR_JAVA (basetype) && (current_lang_depth () == 0))
	TYPE_FOR_JAVA (ref) = 1;
      base_binfo = NULL_TREE;
      if (CLASS_TYPE_P (basetype) && !dependent_type_p (basetype))
	{
	  base_binfo = TYPE_BINFO (basetype);
	  basetype = BINFO_TYPE (base_binfo);
	  TYPE_HAS_NEW_OPERATOR (ref)
	    |= TYPE_HAS_NEW_OPERATOR (basetype);
	  TYPE_HAS_ARRAY_NEW_OPERATOR (ref)
	    |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype);
	  TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
	  TYPE_HAS_CONVERSION (ref) |= TYPE_HAS_CONVERSION (basetype);
	  CLASSTYPE_DIAMOND_SHAPED_P (ref)
	    |= CLASSTYPE_DIAMOND_SHAPED_P (basetype);
	  CLASSTYPE_REPEATED_BASE_P (ref)
	    |= CLASSTYPE_REPEATED_BASE_P (basetype);
	}
      if (TYPE_MARKED_P (basetype))
	{
	  if (basetype == ref)
	    error ("recursive type %qT undefined", basetype);
	  else
	    error ("duplicate base type %qT invalid", basetype);
	  return false;
	}
      TYPE_MARKED_P (basetype) = 1;
      base_binfo = copy_binfo (base_binfo, basetype, ref,
			       &igo_prev, via_virtual);
      if (!BINFO_INHERITANCE_CHAIN (base_binfo))
	BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
      BINFO_BASE_APPEND (binfo, base_binfo);
      BINFO_BASE_ACCESS_APPEND (binfo, access);
    }
  if (VEC_space (tree, CLASSTYPE_VBASECLASSES (ref), 1))
    CLASSTYPE_DIAMOND_SHAPED_P (ref) = 1;
  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 0;
  TYPE_MARKED_P (ref) = 0;
  if (!CLASSTYPE_REPEATED_BASE_P (ref))
    {
      for (base_binfo = binfo; base_binfo;
	   base_binfo = TREE_CHAIN (base_binfo))
	{
	  if (TYPE_MARKED_P (BINFO_TYPE (base_binfo)))
	    {
	      CLASSTYPE_REPEATED_BASE_P (ref) = 1;
	      break;
	    }
	  TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 1;
	}
      for (base_binfo = binfo; base_binfo;
	   base_binfo = TREE_CHAIN (base_binfo))
	if (TYPE_MARKED_P (BINFO_TYPE (base_binfo)))
	  TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 0;
	else
	  break;
    }
  return true;
}
bool xref_basetypes ( tree ref , tree base_list ) { tree * basep ; tree binfo , base_binfo ; unsigned max_vbases = 0 ; unsigned max_bases = 0 ; int i ; tree default_access ; tree igo_prev ; if ( ref == error_mark_node ) return false ; default_access = ( TREE_CODE ( ref ) == RECORD_TYPE && CLASSTYPE_DECLARED_CLASS ( ref ) ? access_private_node : access_public_node ) ; basep = & base_list ; while ( * basep ) { tree basetype = TREE_VALUE ( * basep ) ; if ( ! ( processing_template_decl && uses_template_parms ( basetype ) ) && ! complete_type_or_else ( basetype , NULL ) ) * basep = TREE_CHAIN ( * basep ) ; else { max_bases ++ ; if ( TREE_TYPE ( * basep ) ) max_vbases ++ ; if ( CLASS_TYPE_P ( basetype ) ) max_vbases += VEC_length ( tree , CLASSTYPE_VBASECLASSES ( basetype ) ) ; basep = & TREE_CHAIN ( * basep ) ; } } TYPE_MARKED_P ( ref ) = 1 ; gcc_assert ( ! TYPE_BINFO ( ref ) || TYPE_SIZE ( ref ) ) ; gcc_assert ( TYPE_MAIN_VARIANT ( ref ) == ref ) ; binfo = make_tree_binfo ( max_bases ) ; TYPE_BINFO ( ref ) = binfo ; BINFO_OFFSET ( binfo ) = size_zero_node ; BINFO_TYPE ( binfo ) = ref ; if ( max_bases ) { BINFO_BASE_ACCESSES ( binfo ) = VEC_alloc ( tree , gc , max_bases ) ; CLASSTYPE_NON_AGGREGATE ( ref ) = 1 ; if ( TREE_CODE ( ref ) == UNION_TYPE ) { error ( " " , ref ) ; return false ; } } if ( max_bases > 1 ) { if ( TYPE_FOR_JAVA ( ref ) ) { error ( " " , ref ) ; return false ; } } if ( max_vbases ) { CLASSTYPE_VBASECLASSES ( ref ) = VEC_alloc ( tree , gc , max_vbases ) ; if ( TYPE_FOR_JAVA ( ref ) ) { error ( " " , ref ) ; return false ; } } for ( igo_prev = binfo ; base_list ; base_list = TREE_CHAIN ( base_list ) ) { tree access = TREE_PURPOSE ( base_list ) ; int via_virtual = TREE_TYPE ( base_list ) != NULL_TREE ; tree basetype = TREE_VALUE ( base_list ) ; if ( access == access_default_node ) access = default_access ; if ( TREE_CODE ( basetype ) == TYPE_DECL ) basetype = TREE_TYPE ( basetype ) ; if ( TREE_CODE ( basetype ) != RECORD_TYPE && TREE_CODE ( basetype ) != TYPENAME_TYPE && TREE_CODE ( basetype ) != TEMPLATE_TYPE_PARM && TREE_CODE ( basetype ) != BOUND_TEMPLATE_TEMPLATE_PARM ) { error ( " " , basetype ) ; return false ; } if ( TYPE_FOR_JAVA ( basetype ) && ( current_lang_depth ( ) == 0 ) ) TYPE_FOR_JAVA ( ref ) = 1 ; base_binfo = NULL_TREE ; if ( CLASS_TYPE_P ( basetype ) && ! dependent_type_p ( basetype ) ) { base_binfo = TYPE_BINFO ( basetype ) ; basetype = BINFO_TYPE ( base_binfo ) ; TYPE_HAS_NEW_OPERATOR ( ref ) |= TYPE_HAS_NEW_OPERATOR ( basetype ) ; TYPE_HAS_ARRAY_NEW_OPERATOR ( ref ) |= TYPE_HAS_ARRAY_NEW_OPERATOR ( basetype ) ; TYPE_GETS_DELETE ( ref ) |= TYPE_GETS_DELETE ( basetype ) ; TYPE_HAS_CONVERSION ( ref ) |= TYPE_HAS_CONVERSION ( basetype ) ; CLASSTYPE_DIAMOND_SHAPED_P ( ref ) |= CLASSTYPE_DIAMOND_SHAPED_P ( basetype ) ; CLASSTYPE_REPEATED_BASE_P ( ref ) |= CLASSTYPE_REPEATED_BASE_P ( basetype ) ; } if ( TYPE_MARKED_P ( basetype ) ) { if ( basetype == ref ) error ( " " , basetype ) ; else error ( " " , basetype ) ; return false ; } TYPE_MARKED_P ( basetype ) = 1 ; base_binfo = copy_binfo ( base_binfo , basetype , ref , & igo_prev , via_virtual ) ; if ( ! BINFO_INHERITANCE_CHAIN ( base_binfo ) ) BINFO_INHERITANCE_CHAIN ( base_binfo ) = binfo ; BINFO_BASE_APPEND ( binfo , base_binfo ) ; BINFO_BASE_ACCESS_APPEND ( binfo , access ) ; } if ( VEC_space ( tree , CLASSTYPE_VBASECLASSES ( ref ) , 1 ) ) CLASSTYPE_DIAMOND_SHAPED_P ( ref ) = 1 ; for ( i = 0 ; BINFO_BASE_ITERATE ( binfo , i , base_binfo ) ; i ++ ) TYPE_MARKED_P ( BINFO_TYPE ( base_binfo ) ) = 0 ; TYPE_MARKED_P ( ref ) = 0 ; if ( ! CLASSTYPE_REPEATED_BASE_P ( ref ) ) { for ( base_binfo = binfo ; base_binfo ; base_binfo = TREE_CHAIN ( base_binfo ) ) { if ( TYPE_MARKED_P ( BINFO_TYPE ( base_binfo ) ) ) { CLASSTYPE_REPEATED_BASE_P ( ref ) = 1 ; break ; } TYPE_MARKED_P ( BINFO_TYPE ( base_binfo ) ) = 1 ; } for ( base_binfo = binfo ; base_binfo ; base_binfo = TREE_CHAIN ( base_binfo ) ) if ( TYPE_MARKED_P ( BINFO_TYPE ( base_binfo ) ) ) TYPE_MARKED_P ( BINFO_TYPE ( base_binfo ) ) = 0 ; else break ; } return true ; }
Create the binfo hierarchy for REF with (possibly NULL) base list
BASE_LIST.
Create the binfo hierarchy for REF with ( possibly NULL ) base list BASE_LIST .
/* Maximum direct & indirect virtual bases.  */ /* Maximum direct bases.  */ /* Track Inheritance Graph Order.  */ /* The base of a derived class is private by default, all others are
     public.  */ /* First, make sure that any templates in base-classes are
     instantiated.  This ensures that if we call ourselves recursively
     we do not get confused about which classes are marked and which
     are not.  */ /* An incomplete type.  Remove it from the list.  */ /* The binfo slot should be empty, unless this is an (ill-formed)
     redefinition.  */ /* An aggregate cannot have baseclasses.  */ /* The original basetype could have been a typedef'd type.  */ /* Inherit flags from the base.  */ /* We must do this test after we've seen through a typedef
	 type.  */ /* If we have space in the vbase vector, we must have shared at
       least one of them, and are therefore diamond shaped.  */ /* Unmark all the types.  */ /* Now see if we have a repeated base type.  */