FreeBSD/cddl/contrib/opensolaris/tools/ctf/cvt/tdata.c
/*
 * The layout hash is used during the equivalency checking.  We have a node in
 * the child graph that may be equivalent to a node in the parent graph.  To
 * find the corresponding node (if any) in the parent, we need a quick way to
 * get to all nodes in the parent that look like the node in the child.  Since a
 * large number of nodes don't have names, we need to incorporate the layout of
 * the node into the hash.  If we don't, we'll end up with the vast majority of
 * nodes in bucket zero, with one or two nodes in each of the remaining buckets.
 *
 * There are a couple of constraints, both of which concern forward
 * declarations.  Recall that a forward declaration tdesc is equivalent to a
 * tdesc that actually defines the structure or union.  As such, we cannot
 * incorporate anything into the hash for a named struct or union node that
 * couldn't be found by looking at the forward, and vice versa.
 */
The layout hash is used during the equivalency checking.  We have a node in
the child graph that may be equivalent to a node in the parent graph.  To
find the corresponding node (if any) in the parent, we need a quick way to
get to all nodes in the parent that look like the node in the child.  Since a
large number of nodes don't have names, we need to incorporate the layout of
the node into the hash.  If we don't, we'll end up with the vast majority of
nodes in bucket zero, with one or two nodes in each of the remaining buckets.

There are a couple of constraints, both of which concern forward
declarations.  Recall that a forward declaration tdesc is equivalent to a
tdesc that actually defines the structure or union.  As such, we cannot
incorporate anything into the hash for a named struct or union node that
couldn't be found by looking at the forward, and vice versa.
The layout hash is used during the equivalency checking . We have a node in the child graph that may be equivalent to a node in the parent graph . To find the corresponding node ( if any ) in the parent we need a quick way to get to all nodes in the parent that look like the node in the child . Since a large number of nodes don ' t have names we need to incorporate the layout of the node into the hash . If we don ' t we ' ll end up with the vast majority of nodes in bucket zero with one or two nodes in each of the remaining buckets . There are a couple of constraints both of which concern forward declarations . Recall that a forward declaration tdesc is equivalent to a tdesc that actually defines the structure or union . As such we cannot incorporate anything into the hash for a named struct or union node that couldn ' t be found by looking at the forward and vice versa .
int
tdesc_layouthash(int nbuckets, void *node)
{
	tdesc_t *tdp = node;
	char *name = NULL;
	ulong_t h = 0;
	if (tdp->t_name)
		name = tdp->t_name;
	else {
		switch (tdp->t_type) {
		case POINTER:
		case TYPEDEF:
		case VOLATILE:
		case CONST:
		case RESTRICT:
			name = tdp->t_tdesc->t_name;
			break;
		case FUNCTION:
			h = tdp->t_fndef->fn_nargs +
			    tdp->t_fndef->fn_vargs;
			name = tdp->t_fndef->fn_ret->t_name;
			break;
		case ARRAY:
			h = tdp->t_ardef->ad_nelems;
			name = tdp->t_ardef->ad_contents->t_name;
			break;
		case STRUCT:
		case UNION:
			if (tdp->t_members != NULL)
				name = tdp->t_members->ml_name;
			break;
		case ENUM:
			name = tdp->t_emem->el_name;
			break;
		default:
			warning("Unexpected unnamed %d tdesc (ID %d)\n",
			    tdp->t_type, tdp->t_id);
		}
	}
	if (name)
		return (hash_name(nbuckets, name));
	return (h % nbuckets);
}
int tdesc_layouthash ( int nbuckets , void * node ) { tdesc_t * tdp = node ; char * name = NULL ; ulong_t h = 0 ; if ( tdp -> t_name ) name = tdp -> t_name ; else { switch ( tdp -> t_type ) { case POINTER : case TYPEDEF : case VOLATILE : case CONST : case RESTRICT : name = tdp -> t_tdesc -> t_name ; break ; case FUNCTION : h = tdp -> t_fndef -> fn_nargs + tdp -> t_fndef -> fn_vargs ; name = tdp -> t_fndef -> fn_ret -> t_name ; break ; case ARRAY : h = tdp -> t_ardef -> ad_nelems ; name = tdp -> t_ardef -> ad_contents -> t_name ; break ; case STRUCT : case UNION : if ( tdp -> t_members != NULL ) name = tdp -> t_members -> ml_name ; break ; case ENUM : name = tdp -> t_emem -> el_name ; break ; default : warning ( " \n " , tdp -> t_type , tdp -> t_id ) ; } } if ( name ) return ( hash_name ( nbuckets , name ) ) ; return ( h % nbuckets ) ; }
The layout hash is used during the equivalency checking.
The layout hash is used during the equivalency checking .
/*
			 * Unnamed structures, which cannot have forward
			 * declarations pointing to them.  We can therefore
			 * incorporate the name of the first member into
			 * the hash value, assuming there are any.
			 */ /* Use the first element in the hash value */ /*
			 * Intrinsics, forwards, and typedefs all have
			 * names.
			 */