#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "tree-hasher.h"
#include "stor-layout.h"
#include "print-tree.h"
#include "tree-iterator.h"
static tree bot_manip (tree *, int *, void *);
static tree bot_replace (tree *, int *, void *);
-static int list_hash_eq (const void *, const void *);
static hashval_t list_hash_pieces (tree, tree, tree);
-static hashval_t list_hash (const void *);
static tree build_target_expr (tree, tree, tsubst_flags_t);
static tree count_trees_r (tree *, int *, void *);
static tree verify_stmt_tree_r (tree *, int *, void *);
}
\f
+struct cplus_array_info
+{
+ tree type;
+ tree domain;
+};
+
+struct cplus_array_hasher : ggc_hasher<tree>
+{
+ typedef cplus_array_info *compare_type;
+
+ static hashval_t hash (tree t);
+ static bool equal (tree, cplus_array_info *);
+};
+
/* Hash an ARRAY_TYPE. K is really of type `tree'. */
-static hashval_t
-cplus_array_hash (const void* k)
+hashval_t
+cplus_array_hasher::hash (tree t)
{
hashval_t hash;
- const_tree const t = (const_tree) k;
hash = TYPE_UID (TREE_TYPE (t));
if (TYPE_DOMAIN (t))
return hash;
}
-typedef struct cplus_array_info {
- tree type;
- tree domain;
-} cplus_array_info;
-
/* Compare two ARRAY_TYPEs. K1 is really of type `tree', K2 is really
of type `cplus_array_info*'. */
-static int
-cplus_array_compare (const void * k1, const void * k2)
+bool
+cplus_array_hasher::equal (tree t1, cplus_array_info *t2)
{
- const_tree const t1 = (const_tree) k1;
- const cplus_array_info *const t2 = (const cplus_array_info*) k2;
-
return (TREE_TYPE (t1) == t2->type && TYPE_DOMAIN (t1) == t2->domain);
}
/* Hash table containing dependent array types, which are unsuitable for
the language-independent type hash table. */
-static GTY ((param_is (union tree_node))) htab_t cplus_array_htab;
+static GTY (()) hash_table<cplus_array_hasher> *cplus_array_htab;
/* Build an ARRAY_TYPE without laying it out. */
{
/* Since type_hash_canon calls layout_type, we need to use our own
hash table. */
- void **e;
cplus_array_info cai;
hashval_t hash;
if (cplus_array_htab == NULL)
- cplus_array_htab = htab_create_ggc (61, &cplus_array_hash,
- &cplus_array_compare, NULL);
+ cplus_array_htab = hash_table<cplus_array_hasher>::create_ggc (61);
hash = TYPE_UID (elt_type);
if (index_type)
cai.type = elt_type;
cai.domain = index_type;
- e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, INSERT);
+ tree *e = cplus_array_htab->find_slot_with_hash (&cai, hash, INSERT);
if (*e)
/* We have found the type: we're done. */
return (tree) *e;
/* Hashing of lists so that we don't make duplicates.
The entry point is `list_hash_canon'. */
-/* Now here is the hash table. When recording a list, it is added
- to the slot whose index is the hash code mod the table size.
- Note that the hash table is used for several kinds of lists.
- While all these live in the same table, they are completely independent,
- and the hash code is computed differently for each of these. */
-
-static GTY ((param_is (union tree_node))) htab_t list_hash_table;
-
struct list_proxy
{
tree purpose;
tree chain;
};
+struct list_hasher : ggc_hasher<tree>
+{
+ typedef list_proxy *compare_type;
+
+ static hashval_t hash (tree);
+ static bool equal (tree, list_proxy *);
+};
+
+/* Now here is the hash table. When recording a list, it is added
+ to the slot whose index is the hash code mod the table size.
+ Note that the hash table is used for several kinds of lists.
+ While all these live in the same table, they are completely independent,
+ and the hash code is computed differently for each of these. */
+
+static GTY (()) hash_table<list_hasher> *list_hash_table;
+
/* Compare ENTRY (an entry in the hash table) with DATA (a list_proxy
for a node we are thinking about adding). */
-static int
-list_hash_eq (const void* entry, const void* data)
+bool
+list_hasher::equal (tree t, list_proxy *proxy)
{
- const_tree const t = (const_tree) entry;
- const struct list_proxy *const proxy = (const struct list_proxy *) data;
-
return (TREE_VALUE (t) == proxy->value
&& TREE_PURPOSE (t) == proxy->purpose
&& TREE_CHAIN (t) == proxy->chain);
/* Hash an already existing TREE_LIST. */
-static hashval_t
-list_hash (const void* p)
+hashval_t
+list_hasher::hash (tree t)
{
- const_tree const t = (const_tree) p;
return list_hash_pieces (TREE_PURPOSE (t),
TREE_VALUE (t),
TREE_CHAIN (t));
hash_tree_cons (tree purpose, tree value, tree chain)
{
int hashcode = 0;
- void **slot;
+ tree *slot;
struct list_proxy proxy;
/* Hash the list node. */
proxy.value = value;
proxy.chain = chain;
/* See if it is already in the table. */
- slot = htab_find_slot_with_hash (list_hash_table, &proxy, hashcode,
- INSERT);
+ slot = list_hash_table->find_slot_with_hash (&proxy, hashcode, INSERT);
/* If not, create a new node. */
if (!*slot)
*slot = tree_cons (purpose, value, chain);
void
init_tree (void)
{
- list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL);
+ list_hash_table = hash_table<list_hasher>::create_ggc (61);
}
/* Returns the kind of special function that DECL (a FUNCTION_DECL)