aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorTrevor Saunders <tsaunders@mozilla.com>2014-10-12 22:22:53 +0000
committerTrevor Saunders <tbsaunde@gcc.gnu.org>2014-10-12 22:22:53 +0000
commit2a22f99cb12d82712dd93cfef808b1cef543601b (patch)
treec828063f153ceb609ce5c7d44ea9f00391b32950 /gcc/cp
parent7b262a51ea2310bdb6cc901de00f04b0e7be0a4e (diff)
downloadgcc-2a22f99cb12d82712dd93cfef808b1cef543601b.zip
gcc-2a22f99cb12d82712dd93cfef808b1cef543601b.tar.gz
gcc-2a22f99cb12d82712dd93cfef808b1cef543601b.tar.bz2
move many gc hashtab to hash_table
gcc/ * asan.c, cfgloop.c, cfgloop.h, cgraph.c, cgraph.h, config/darwin.c, config/m32c/m32c.c, config/mep/mep.c, config/mips/mips.c, config/rs6000/rs6000.c, dwarf2out.c, function.c, function.h, gimple-ssa.h, libfuncs.h, optabs.c, output.h, rtl.h, sese.c, symtab.c, tree-cfg.c, tree-dfa.c, tree-ssa.c, varasm.c: Use hash-table instead of hashtab. * doc/gty.texi (for_user): Document new option. * gengtype.c (create_user_defined_type): Don't try to get a struct for char. (walk_type): Don't error out on for_user option. (write_func_for_structure): Emit user marking routines if requested by for_user option. (write_local_func_for_structure): Likewise. (main): Mark types with for_user option as used. * ggc.h (gt_pch_nx): Add overload for unsigned int. * hash-map.h (hash_map::hash_entry::pch_nx_helper): AddOverloads. * hash-table.h (ggc_hasher): New struct. (hash_table::create_ggc): New function. (gt_pch_nx): New overload for hash_table. java/ * class.c, decl.c, except.c, expr.c, java-tree.h, lang.c: Use hash_table instead of hashtab. objc/ * objc-act.c: use hash_table instead of hashtab. cp/ * cp-gimplify.c, cp-tree.h, decl.c, mangle.c, name-lookup.c, pt.c, semantics.c, tree.c, typeck2.c: Use hash_table instead of hashtab. fortran/ * trans-decl.c, trans.c, trans.h: Use hash_table instead of hashtab. c-family/ * c-common.c: Use hash_table instead of hashtab. From-SVN: r216127
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-gimplify.c14
-rw-r--r--gcc/cp/cp-tree.h21
-rw-r--r--gcc/cp/decl.c124
-rw-r--r--gcc/cp/mangle.c35
-rw-r--r--gcc/cp/name-lookup.c11
-rw-r--r--gcc/cp/pt.c82
-rw-r--r--gcc/cp/semantics.c74
-rw-r--r--gcc/cp/tree.c85
-rw-r--r--gcc/cp/typeck2.c47
10 files changed, 251 insertions, 248 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ebb62d2..18eef9a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
+
+ * cp-gimplify.c, cp-tree.h, decl.c, mangle.c, name-lookup.c,
+ pt.c, semantics.c, tree.c, typeck2.c: Use hash_table instead of
+ hashtab.
+
2014-10-10 Jason Merrill <jason@redhat.com>
PR c++/62115
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index e2bf547..22703b7 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -758,20 +758,18 @@ is_invisiref_parm (const_tree t)
/* Return true if the uid in both int tree maps are equal. */
-int
-cxx_int_tree_map_eq (const void *va, const void *vb)
+bool
+cxx_int_tree_map_hasher::equal (cxx_int_tree_map *a, cxx_int_tree_map *b)
{
- const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
- const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
return (a->uid == b->uid);
}
/* Hash a UID in a cxx_int_tree_map. */
unsigned int
-cxx_int_tree_map_hash (const void *item)
+cxx_int_tree_map_hasher::hash (cxx_int_tree_map *item)
{
- return ((const struct cxx_int_tree_map *)item)->uid;
+ return item->uid;
}
/* A stable comparison routine for use with splay trees and DECLs. */
@@ -911,9 +909,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
{
struct cxx_int_tree_map *h, in;
in.uid = DECL_UID (stmt);
- h = (struct cxx_int_tree_map *)
- htab_find_with_hash (cp_function_chain->extern_decl_map,
- &in, in.uid);
+ h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
if (h)
{
*stmt_p = h->to;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6d720c1..dbbf26d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1133,13 +1133,24 @@ struct GTY(()) saved_scope {
extern GTY(()) struct saved_scope *scope_chain;
-struct GTY(()) cxx_int_tree_map {
+struct GTY((for_user)) cxx_int_tree_map {
unsigned int uid;
tree to;
};
-extern unsigned int cxx_int_tree_map_hash (const void *);
-extern int cxx_int_tree_map_eq (const void *, const void *);
+struct cxx_int_tree_map_hasher : ggc_hasher<cxx_int_tree_map *>
+{
+ static hashval_t hash (cxx_int_tree_map *);
+ static bool equal (cxx_int_tree_map *, cxx_int_tree_map *);
+};
+
+struct named_label_entry;
+
+struct named_label_hasher : ggc_hasher<named_label_entry *>
+{
+ static hashval_t hash (named_label_entry *);
+ static bool equal (named_label_entry *, named_label_entry *);
+};
/* Global state pertinent to the current function. */
@@ -1165,13 +1176,13 @@ struct GTY(()) language_function {
/* True if this function can throw an exception. */
BOOL_BITFIELD can_throw : 1;
- htab_t GTY((param_is(struct named_label_entry))) x_named_labels;
+ hash_table<named_label_hasher> *x_named_labels;
cp_binding_level *bindings;
vec<tree, va_gc> *x_local_names;
/* Tracking possibly infinite loops. This is a vec<tree> only because
vec<bool> doesn't work with gtype. */
vec<tree, va_gc> *infinite_loops;
- htab_t GTY((param_is (struct cxx_int_tree_map))) extern_decl_map;
+ hash_table<cxx_int_tree_map_hasher> *extern_decl_map;
};
/* The current C++-specific per-function global variables. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d4adbeb..88164cd 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "tree-hasher.h"
#include "stringpool.h"
#include "stor-layout.h"
#include "varasm.h"
@@ -88,8 +89,6 @@ static int member_function_or_else (tree, tree, enum overload_flags);
static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
int);
static void check_for_uninitialized_const_var (tree);
-static hashval_t typename_hash (const void *);
-static int typename_compare (const void *, const void *);
static tree local_variable_p_walkfn (tree *, int *, void *);
static tree record_builtin_java_type (const char *, int);
static const char *tag_name (enum tag_types);
@@ -210,7 +209,7 @@ struct GTY((chain_next ("%h.next"))) named_label_use_entry {
we can clear out their names' definitions at the end of the
function, and so we can check the validity of jumps to these labels. */
-struct GTY(()) named_label_entry {
+struct GTY((for_user)) named_label_entry {
/* The decl itself. */
tree label_decl;
@@ -394,11 +393,10 @@ pop_label (tree label, tree old_value)
go out of scope. BLOCK is the top-level block for the
function. */
-static int
-pop_labels_1 (void **slot, void *data)
+int
+pop_labels_1 (named_label_entry **slot, tree block)
{
- struct named_label_entry *ent = (struct named_label_entry *) *slot;
- tree block = (tree) data;
+ struct named_label_entry *ent = *slot;
pop_label (ent->label_decl, NULL_TREE);
@@ -407,7 +405,7 @@ pop_labels_1 (void **slot, void *data)
DECL_CHAIN (ent->label_decl) = BLOCK_VARS (block);
BLOCK_VARS (block) = ent->label_decl;
- htab_clear_slot (named_labels, slot);
+ named_labels->clear_slot (slot);
return 1;
}
@@ -417,7 +415,7 @@ pop_labels (tree block)
{
if (named_labels)
{
- htab_traverse (named_labels, pop_labels_1, block);
+ named_labels->traverse<tree, pop_labels_1> (block);
named_labels = NULL;
}
}
@@ -428,13 +426,12 @@ static void
pop_local_label (tree label, tree old_value)
{
struct named_label_entry dummy;
- void **slot;
pop_label (label, old_value);
dummy.label_decl = label;
- slot = htab_find_slot (named_labels, &dummy, NO_INSERT);
- htab_clear_slot (named_labels, slot);
+ named_label_entry **slot = named_labels->find_slot (&dummy, NO_INSERT);
+ named_labels->clear_slot (slot);
}
/* The following two routines are used to interface to Objective-C++.
@@ -474,11 +471,10 @@ objc_mark_locals_volatile (void *enclosing_blk)
/* Update data for defined and undefined labels when leaving a scope. */
-static int
-poplevel_named_label_1 (void **slot, void *data)
+int
+poplevel_named_label_1 (named_label_entry **slot, cp_binding_level *bl)
{
- struct named_label_entry *ent = (struct named_label_entry *) *slot;
- cp_binding_level *bl = (cp_binding_level *) data;
+ named_label_entry *ent = *slot;
cp_binding_level *obl = bl->level_chain;
if (ent->binding_level == bl)
@@ -585,8 +581,8 @@ poplevel (int keep, int reverse, int functionbody)
/* Any uses of undefined labels, and any defined labels, now operate
under constraints of next binding contour. */
if (cfun && !functionbody && named_labels)
- htab_traverse (named_labels, poplevel_named_label_1,
- current_binding_level);
+ named_labels->traverse<cp_binding_level *, poplevel_named_label_1>
+ (current_binding_level);
/* Get the decls in the order they were written.
Usually current_binding_level->names is in reverse order.
@@ -2717,19 +2713,16 @@ redeclaration_error_message (tree newdecl, tree olddecl)
/* Hash and equality functions for the named_label table. */
-static hashval_t
-named_label_entry_hash (const void *data)
+hashval_t
+named_label_hasher::hash (named_label_entry *ent)
{
- const struct named_label_entry *ent = (const struct named_label_entry *) data;
return DECL_UID (ent->label_decl);
}
-static int
-named_label_entry_eq (const void *a, const void *b)
+bool
+named_label_hasher::equal (named_label_entry *a, named_label_entry *b)
{
- const struct named_label_entry *ent_a = (const struct named_label_entry *) a;
- const struct named_label_entry *ent_b = (const struct named_label_entry *) b;
- return ent_a->label_decl == ent_b->label_decl;
+ return a->label_decl == b->label_decl;
}
/* Create a new label, named ID. */
@@ -2738,7 +2731,6 @@ static tree
make_label_decl (tree id, int local_p)
{
struct named_label_entry *ent;
- void **slot;
tree decl;
decl = build_decl (input_location, LABEL_DECL, id, void_type_node);
@@ -2756,8 +2748,7 @@ make_label_decl (tree id, int local_p)
/* Create the label htab for the function on demand. */
if (!named_labels)
- named_labels = htab_create_ggc (13, named_label_entry_hash,
- named_label_entry_eq, NULL);
+ named_labels = hash_table<named_label_hasher>::create_ggc (13);
/* Record this label on the list of labels used in this function.
We do this before calling make_label_decl so that we get the
@@ -2765,7 +2756,7 @@ make_label_decl (tree id, int local_p)
ent = ggc_cleared_alloc<named_label_entry> ();
ent->label_decl = decl;
- slot = htab_find_slot (named_labels, ent, INSERT);
+ named_label_entry **slot = named_labels->find_slot (ent, INSERT);
gcc_assert (*slot == NULL);
*slot = ent;
@@ -2979,7 +2970,7 @@ check_goto (tree decl)
return;
dummy.label_decl = decl;
- ent = (struct named_label_entry *) htab_find (named_labels, &dummy);
+ ent = named_labels->find (&dummy);
gcc_assert (ent != NULL);
/* If the label hasn't been defined yet, defer checking. */
@@ -3089,7 +3080,7 @@ define_label_1 (location_t location, tree name)
decl = lookup_label (name);
dummy.label_decl = decl;
- ent = (struct named_label_entry *) htab_find (named_labels, &dummy);
+ ent = named_labels->find (&dummy);
gcc_assert (ent != NULL);
/* After labels, make any new cleanups in the function go into their
@@ -3264,50 +3255,50 @@ finish_case_label (location_t loc, tree low_value, tree high_value)
return r;
}
-/* Hash a TYPENAME_TYPE. K is really of type `tree'. */
-
-static hashval_t
-typename_hash (const void* k)
-{
- hashval_t hash;
- const_tree const t = (const_tree) k;
-
- hash = (htab_hash_pointer (TYPE_CONTEXT (t))
- ^ htab_hash_pointer (TYPE_IDENTIFIER (t)));
-
- return hash;
-}
-
-typedef struct typename_info {
+struct typename_info {
tree scope;
tree name;
tree template_id;
bool enum_p;
bool class_p;
-} typename_info;
-
-/* Compare two TYPENAME_TYPEs. K1 is really of type `tree', K2 is
- really of type `typename_info*' */
+};
-static int
-typename_compare (const void * k1, const void * k2)
+struct typename_hasher : ggc_hasher<tree>
{
- const_tree const t1 = (const_tree) k1;
- const typename_info *const t2 = (const typename_info *) k2;
+ typedef typename_info *compare_type;
- return (TYPE_IDENTIFIER (t1) == t2->name
- && TYPE_CONTEXT (t1) == t2->scope
- && TYPENAME_TYPE_FULLNAME (t1) == t2->template_id
- && TYPENAME_IS_ENUM_P (t1) == t2->enum_p
- && TYPENAME_IS_CLASS_P (t1) == t2->class_p);
-}
+ /* Hash a TYPENAME_TYPE. */
+
+ static hashval_t
+ hash (tree t)
+ {
+ hashval_t hash;
+
+ hash = (htab_hash_pointer (TYPE_CONTEXT (t))
+ ^ htab_hash_pointer (TYPE_IDENTIFIER (t)));
+
+ return hash;
+ }
+
+ /* Compare two TYPENAME_TYPEs. */
+
+ static bool
+ equal (tree t1, const typename_info *t2)
+ {
+ return (TYPE_IDENTIFIER (t1) == t2->name
+ && TYPE_CONTEXT (t1) == t2->scope
+ && TYPENAME_TYPE_FULLNAME (t1) == t2->template_id
+ && TYPENAME_IS_ENUM_P (t1) == t2->enum_p
+ && TYPENAME_IS_CLASS_P (t1) == t2->class_p);
+ }
+};
/* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is
the type of `T', NAME is the IDENTIFIER_NODE for `t'.
Returns the new TYPENAME_TYPE. */
-static GTY ((param_is (union tree_node))) htab_t typename_htab;
+static GTY (()) hash_table<typename_hasher> *typename_htab;
static tree
build_typename_type (tree context, tree name, tree fullname,
@@ -3316,12 +3307,11 @@ build_typename_type (tree context, tree name, tree fullname,
tree t;
tree d;
typename_info ti;
- void **e;
+ tree *e;
hashval_t hash;
if (typename_htab == NULL)
- typename_htab = htab_create_ggc (61, &typename_hash,
- &typename_compare, NULL);
+ typename_htab = hash_table<typename_hasher>::create_ggc (61);
ti.scope = FROB_CONTEXT (context);
ti.name = name;
@@ -3334,9 +3324,9 @@ build_typename_type (tree context, tree name, tree fullname,
^ htab_hash_pointer (ti.name));
/* See if we already have this type. */
- e = htab_find_slot_with_hash (typename_htab, &ti, hash, INSERT);
+ e = typename_htab->find_slot_with_hash (&ti, hash, INSERT);
if (*e)
- t = (tree) *e;
+ t = *e;
else
{
/* Build the TYPENAME_TYPE. */
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 6e6aa8a..6b8f706 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "tree-hasher.h"
#include "stor-layout.h"
#include "stringpool.h"
#include "tm_p.h"
@@ -3690,26 +3691,32 @@ mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
return result;
}
+struct conv_type_hasher : ggc_hasher<tree>
+{
+ static hashval_t hash (tree);
+ static bool equal (tree, tree);
+};
+
/* This hash table maps TYPEs to the IDENTIFIER for a conversion
operator to TYPE. The nodes are IDENTIFIERs whose TREE_TYPE is the
TYPE. */
-static GTY ((param_is (union tree_node))) htab_t conv_type_names;
+static GTY (()) hash_table<conv_type_hasher> *conv_type_names;
/* Hash a node (VAL1) in the table. */
-static hashval_t
-hash_type (const void *val)
+hashval_t
+conv_type_hasher::hash (tree val)
{
- return (hashval_t) TYPE_UID (TREE_TYPE ((const_tree) val));
+ return (hashval_t) TYPE_UID (TREE_TYPE (val));
}
/* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */
-static int
-compare_type (const void *val1, const void *val2)
+bool
+conv_type_hasher::equal (tree val1, tree val2)
{
- return TREE_TYPE ((const_tree) val1) == (const_tree) val2;
+ return TREE_TYPE (val1) == val2;
}
/* Return an identifier for the mangled unqualified name for a
@@ -3719,25 +3726,25 @@ compare_type (const void *val1, const void *val2)
tree
mangle_conv_op_name_for_type (const tree type)
{
- void **slot;
+ tree *slot;
tree identifier;
if (type == error_mark_node)
return error_mark_node;
if (conv_type_names == NULL)
- conv_type_names = htab_create_ggc (31, &hash_type, &compare_type, NULL);
+ conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);
- slot = htab_find_slot_with_hash (conv_type_names, type,
- (hashval_t) TYPE_UID (type), INSERT);
- identifier = (tree)*slot;
+ slot = conv_type_names->find_slot_with_hash (type,
+ (hashval_t) TYPE_UID (type),
+ INSERT);
+ identifier = *slot;
if (!identifier)
{
char buffer[64];
/* Create a unique name corresponding to TYPE. */
- sprintf (buffer, "operator %lu",
- (unsigned long) htab_elements (conv_type_names));
+ sprintf (buffer, "operator %lu", conv_type_names->elements ());
identifier = get_identifier (buffer);
*slot = identifier;
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index ebcbb5c..d42bcac 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -766,22 +766,19 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
middle end. */
{
struct cxx_int_tree_map *h;
- void **loc;
TREE_PUBLIC (x) = TREE_PUBLIC (t);
if (cp_function_chain->extern_decl_map == NULL)
cp_function_chain->extern_decl_map
- = htab_create_ggc (20, cxx_int_tree_map_hash,
- cxx_int_tree_map_eq, NULL);
+ = hash_table<cxx_int_tree_map_hasher>::create_ggc (20);
h = ggc_alloc<cxx_int_tree_map> ();
h->uid = DECL_UID (x);
h->to = t;
- loc = htab_find_slot_with_hash
- (cp_function_chain->extern_decl_map, h,
- h->uid, INSERT);
- *(struct cxx_int_tree_map **) loc = h;
+ cxx_int_tree_map **loc = cp_function_chain->extern_decl_map
+ ->find_slot (h, INSERT);
+ *loc = h;
}
}
else if (TREE_CODE (t) == PARM_DECL)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f2c21ee..47b5d93 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -80,18 +80,22 @@ static tree cur_stmt_expr;
/* True if we've recursed into fn_type_unification too many times. */
static bool excessive_deduction_depth;
-typedef struct GTY(()) spec_entry
+struct GTY((for_user)) spec_entry
{
tree tmpl;
tree args;
tree spec;
-} spec_entry;
+};
+
+struct spec_hasher : ggc_hasher<spec_entry *>
+{
+ static hashval_t hash (spec_entry *);
+ static bool equal (spec_entry *, spec_entry *);
+};
-static GTY ((param_is (spec_entry)))
- htab_t decl_specializations;
+static GTY (()) hash_table<spec_hasher> *decl_specializations;
-static GTY ((param_is (spec_entry)))
- htab_t type_specializations;
+static GTY (()) hash_table<spec_hasher> *type_specializations;
/* Contains canonical template parameter types. The vector is indexed by
the TEMPLATE_TYPE_IDX of the template parameter. Each element is a
@@ -153,7 +157,6 @@ static bool inline_needs_template_parms (tree, bool);
static void push_inline_template_parms_recursive (tree, int);
static tree retrieve_local_specialization (tree);
static void register_local_specialization (tree, tree);
-static hashval_t hash_specialization (const void *p);
static tree reduce_template_parm_level (tree, tree, int, tree, tsubst_flags_t);
static int mark_template_parm (tree, void *);
static int template_parm_this_level_p (tree, void *);
@@ -931,18 +934,18 @@ maybe_process_partial_specialization (tree type)
new member specialization template. */
spec_entry elt;
spec_entry *entry;
- void **slot;
elt.tmpl = most_general_template (tmpl);
elt.args = CLASSTYPE_TI_ARGS (inst);
elt.spec = inst;
- htab_remove_elt (type_specializations, &elt);
+ type_specializations->remove_elt (&elt);
elt.tmpl = tmpl;
elt.args = INNERMOST_TEMPLATE_ARGS (elt.args);
- slot = htab_find_slot (type_specializations, &elt, INSERT);
+ spec_entry **slot
+ = type_specializations->find_slot (&elt, INSERT);
entry = ggc_alloc<spec_entry> ();
*entry = elt;
*slot = entry;
@@ -1085,7 +1088,7 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
{
spec_entry *found;
spec_entry elt;
- htab_t specializations;
+ hash_table<spec_hasher> *specializations;
elt.tmpl = tmpl;
elt.args = args;
@@ -1097,8 +1100,8 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
specializations = decl_specializations;
if (hash == 0)
- hash = hash_specialization (&elt);
- found = (spec_entry *) htab_find_with_hash (specializations, &elt, hash);
+ hash = spec_hasher::hash (&elt);
+ found = specializations->find_with_hash (&elt, hash);
if (found)
return found->spec;
}
@@ -1343,7 +1346,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
hashval_t hash)
{
tree fn;
- void **slot = NULL;
+ spec_entry **slot = NULL;
spec_entry elt;
gcc_assert ((TREE_CODE (tmpl) == TEMPLATE_DECL && DECL_P (spec))
@@ -1376,10 +1379,10 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
elt.spec = spec;
if (hash == 0)
- hash = hash_specialization (&elt);
+ hash = spec_hasher::hash (&elt);
slot =
- htab_find_slot_with_hash (decl_specializations, &elt, hash, INSERT);
+ decl_specializations->find_slot_with_hash (&elt, hash, INSERT);
if (*slot)
fn = ((spec_entry *) *slot)->spec;
else
@@ -1500,11 +1503,9 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
int comparing_specializations;
-static int
-eq_specializations (const void *p1, const void *p2)
+bool
+spec_hasher::equal (spec_entry *e1, spec_entry *e2)
{
- const spec_entry *e1 = (const spec_entry *)p1;
- const spec_entry *e2 = (const spec_entry *)p2;
int equal;
++comparing_specializations;
@@ -1527,10 +1528,9 @@ hash_tmpl_and_args (tree tmpl, tree args)
/* Returns a hash for a spec_entry node based on the TMPL and ARGS members,
ignoring SPEC. */
-static hashval_t
-hash_specialization (const void *p)
+hashval_t
+spec_hasher::hash (spec_entry *e)
{
- const spec_entry *e = (const spec_entry *)p;
return hash_tmpl_and_args (e->tmpl, e->args);
}
@@ -1710,7 +1710,7 @@ reregister_specialization (tree spec, tree tinfo, tree new_spec)
elt.args = TI_ARGS (tinfo);
elt.spec = NULL_TREE;
- entry = (spec_entry *) htab_find (decl_specializations, &elt);
+ entry = decl_specializations->find (&elt);
if (entry != NULL)
{
gcc_assert (entry->spec == spec || entry->spec == new_spec);
@@ -7418,7 +7418,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
{
tree templ = NULL_TREE, parmlist;
tree t;
- void **slot;
+ spec_entry **slot;
spec_entry *entry;
spec_entry elt;
hashval_t hash;
@@ -7684,9 +7684,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
/* If we already have this specialization, return it. */
elt.tmpl = gen_tmpl;
elt.args = arglist;
- hash = hash_specialization (&elt);
- entry = (spec_entry *) htab_find_with_hash (type_specializations,
- &elt, hash);
+ hash = spec_hasher::hash (&elt);
+ entry = type_specializations->find_with_hash (&elt, hash);
if (entry)
return entry->spec;
@@ -7930,8 +7929,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
elt.spec = t;
- slot = htab_find_slot_with_hash (type_specializations,
- &elt, hash, INSERT);
+ slot = type_specializations->find_slot_with_hash (&elt, hash, INSERT);
entry = ggc_alloc<spec_entry> ();
*entry = elt;
*slot = entry;
@@ -8652,7 +8650,7 @@ tsubst_friend_function (tree decl, tree args)
elt.args = DECL_TI_ARGS (spec);
elt.spec = NULL_TREE;
- htab_remove_elt (decl_specializations, &elt);
+ decl_specializations->remove_elt (&elt);
DECL_TI_ARGS (spec)
= add_outermost_template_args (new_args,
@@ -22316,14 +22314,8 @@ convert_generic_types_to_packs (tree parm, int start_idx, int end_idx)
void
init_template_processing (void)
{
- decl_specializations = htab_create_ggc (37,
- hash_specialization,
- eq_specializations,
- ggc_free);
- type_specializations = htab_create_ggc (37,
- hash_specialization,
- eq_specializations,
- ggc_free);
+ decl_specializations = hash_table<spec_hasher>::create_ggc (37);
+ type_specializations = hash_table<spec_hasher>::create_ggc (37);
}
/* Print stats about the template hash tables for -fstats. */
@@ -22332,13 +22324,13 @@ void
print_template_statistics (void)
{
fprintf (stderr, "decl_specializations: size %ld, %ld elements, "
- "%f collisions\n", (long) htab_size (decl_specializations),
- (long) htab_elements (decl_specializations),
- htab_collisions (decl_specializations));
+ "%f collisions\n", decl_specializations->size (),
+ decl_specializations->elements (),
+ decl_specializations->collisions ());
fprintf (stderr, "type_specializations: size %ld, %ld elements, "
- "%f collisions\n", (long) htab_size (type_specializations),
- (long) htab_elements (type_specializations),
- htab_collisions (type_specializations));
+ "%f collisions\n", type_specializations->size (),
+ type_specializations->elements (),
+ type_specializations->collisions ());
}
#include "gt-cp-pt.h"
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 08658a7..85d5383 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7579,35 +7579,38 @@ ensure_literal_type_for_constexpr_object (tree decl)
/* Representation of entries in the constexpr function definition table. */
-typedef struct GTY(()) constexpr_fundef {
+struct GTY((for_user)) constexpr_fundef {
tree decl;
tree body;
-} constexpr_fundef;
+};
+
+struct constexpr_fundef_hasher : ggc_hasher<constexpr_fundef *>
+{
+ static hashval_t hash (constexpr_fundef *);
+ static bool equal (constexpr_fundef *, constexpr_fundef *);
+};
/* This table holds all constexpr function definitions seen in
the current translation unit. */
-static GTY ((param_is (constexpr_fundef))) htab_t constexpr_fundef_table;
+static GTY (()) hash_table<constexpr_fundef_hasher> *constexpr_fundef_table;
/* Utility function used for managing the constexpr function table.
Return true if the entries pointed to by P and Q are for the
same constexpr function. */
-static inline int
-constexpr_fundef_equal (const void *p, const void *q)
+inline bool
+constexpr_fundef_hasher::equal (constexpr_fundef *lhs, constexpr_fundef *rhs)
{
- const constexpr_fundef *lhs = (const constexpr_fundef *) p;
- const constexpr_fundef *rhs = (const constexpr_fundef *) q;
return lhs->decl == rhs->decl;
}
/* Utility function used for managing the constexpr function table.
Return a hash value for the entry pointed to by Q. */
-static inline hashval_t
-constexpr_fundef_hash (const void *p)
+inline hashval_t
+constexpr_fundef_hasher::hash (constexpr_fundef *fundef)
{
- const constexpr_fundef *fundef = (const constexpr_fundef *) p;
return DECL_UID (fundef->decl);
}
@@ -7621,7 +7624,7 @@ retrieve_constexpr_fundef (tree fun)
return NULL;
fundef.decl = fun;
- return (constexpr_fundef *) htab_find (constexpr_fundef_table, &fundef);
+ return constexpr_fundef_table->find (&fundef);
}
/* Check whether the parameter and return types of FUN are valid for a
@@ -8236,14 +8239,12 @@ register_constexpr_fundef (tree fun, tree body)
/* Create the constexpr function table if necessary. */
if (constexpr_fundef_table == NULL)
- constexpr_fundef_table = htab_create_ggc (101,
- constexpr_fundef_hash,
- constexpr_fundef_equal,
- ggc_free);
+ constexpr_fundef_table
+ = hash_table<constexpr_fundef_hasher>::create_ggc (101);
+
entry.decl = fun;
entry.body = body;
- slot = (constexpr_fundef **)
- htab_find_slot (constexpr_fundef_table, &entry, INSERT);
+ slot = constexpr_fundef_table->find_slot (&entry, INSERT);
gcc_assert (*slot == NULL);
*slot = ggc_alloc<constexpr_fundef> ();
@@ -8296,7 +8297,7 @@ explain_invalid_constexpr_fn (tree fun)
along with the bindings of parameters to their arguments, for
the purpose of compile time evaluation. */
-typedef struct GTY(()) constexpr_call {
+struct GTY((for_user)) constexpr_call {
/* Description of the constexpr function definition. */
constexpr_fundef *fundef;
/* Parameter bindings environment. A TREE_LIST where each TREE_PURPOSE
@@ -8314,39 +8315,42 @@ typedef struct GTY(()) constexpr_call {
/* The hash of this call; we remember it here to avoid having to
recalculate it when expanding the hash table. */
hashval_t hash;
-} constexpr_call;
+};
+
+struct constexpr_call_hasher : ggc_hasher<constexpr_call *>
+{
+ static hashval_t hash (constexpr_call *);
+ static bool equal (constexpr_call *, constexpr_call *);
+ };
/* A table of all constexpr calls that have been evaluated by the
compiler in this translation unit. */
-static GTY ((param_is (constexpr_call))) htab_t constexpr_call_table;
+static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
static tree cxx_eval_constant_expression (const constexpr_call *, tree,
bool, bool, bool *, bool *);
/* Compute a hash value for a constexpr call representation. */
-static hashval_t
-constexpr_call_hash (const void *p)
+inline hashval_t
+constexpr_call_hasher::hash (constexpr_call *info)
{
- const constexpr_call *info = (const constexpr_call *) p;
return info->hash;
}
-/* Return 1 if the objects pointed to by P and Q represent calls
+/* Return true if the objects pointed to by P and Q represent calls
to the same constexpr function with the same arguments.
- Otherwise, return 0. */
+ Otherwise, return false. */
-static int
-constexpr_call_equal (const void *p, const void *q)
+bool
+constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
{
- const constexpr_call *lhs = (const constexpr_call *) p;
- const constexpr_call *rhs = (const constexpr_call *) q;
tree lhs_bindings;
tree rhs_bindings;
if (lhs == rhs)
return 1;
- if (!constexpr_fundef_equal (lhs->fundef, rhs->fundef))
+ if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
return 0;
lhs_bindings = lhs->bindings;
rhs_bindings = rhs->bindings;
@@ -8369,10 +8373,7 @@ static void
maybe_initialize_constexpr_call_table (void)
{
if (constexpr_call_table == NULL)
- constexpr_call_table = htab_create_ggc (101,
- constexpr_call_hash,
- constexpr_call_equal,
- ggc_free);
+ constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
}
/* Return true if T designates the implied `this' parameter. */
@@ -8681,12 +8682,11 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t,
new_call.hash
= iterative_hash_template_arg (new_call.bindings,
- constexpr_fundef_hash (new_call.fundef));
+ constexpr_fundef_hasher::hash (new_call.fundef));
/* If we have seen this call before, we are done. */
maybe_initialize_constexpr_call_table ();
- slot = (constexpr_call **)
- htab_find_slot (constexpr_call_table, &new_call, INSERT);
+ slot = constexpr_call_table->find_slot (&new_call, INSERT);
entry = *slot;
if (entry == NULL)
{
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 5b11d5c..9008cdb 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#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"
@@ -40,9 +41,7 @@ along with GCC; see the file COPYING3. If not see
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 *);
@@ -722,13 +721,26 @@ rvalue (tree expr)
}
+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))
@@ -736,26 +748,18 @@ cplus_array_hash (const void* k)
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. */
@@ -813,13 +817,11 @@ build_cplus_array_type (tree elt_type, tree index_type)
{
/* 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)
@@ -827,7 +829,7 @@ build_cplus_array_type (tree elt_type, tree 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;
@@ -1641,14 +1643,6 @@ copy_binfo (tree binfo, tree type, tree t, tree *igo_prev, int virt)
/* 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;
@@ -1656,15 +1650,28 @@ struct list_proxy
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);
@@ -1695,10 +1702,9 @@ list_hash_pieces (tree purpose, tree value, tree 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));
@@ -1712,7 +1718,7 @@ tree
hash_tree_cons (tree purpose, tree value, tree chain)
{
int hashcode = 0;
- void **slot;
+ tree *slot;
struct list_proxy proxy;
/* Hash the list node. */
@@ -1723,8 +1729,7 @@ hash_tree_cons (tree purpose, tree value, tree chain)
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);
@@ -3670,7 +3675,7 @@ cp_save_expr (tree expr)
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)
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 0a851f1..ad69668 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -135,7 +135,7 @@ cxx_readonly_error (tree arg, enum lvalue_use errstring)
/* Structure that holds information about declarations whose type was
incomplete and we could not check whether it was abstract or not. */
-struct GTY((chain_next ("%h.next"))) pending_abstract_type {
+struct GTY((chain_next ("%h.next"), for_user)) pending_abstract_type {
/* Declaration which we are checking for abstractness. It is either
a DECL node, or an IDENTIFIER_NODE if we do not have a full
declaration available. */
@@ -155,15 +155,19 @@ struct GTY((chain_next ("%h.next"))) pending_abstract_type {
struct pending_abstract_type* next;
};
+struct abstract_type_hasher : ggc_hasher<pending_abstract_type *>
+{
+ typedef tree compare_type;
+ static hashval_t hash (pending_abstract_type *);
+ static bool equal (pending_abstract_type *, tree);
+};
/* Compute the hash value of the node VAL. This function is used by the
hash table abstract_pending_vars. */
-static hashval_t
-pat_calc_hash (const void* val)
+hashval_t
+abstract_type_hasher::hash (pending_abstract_type *pat)
{
- const struct pending_abstract_type *pat =
- (const struct pending_abstract_type *) val;
return (hashval_t) TYPE_UID (pat->type);
}
@@ -171,21 +175,16 @@ pat_calc_hash (const void* val)
/* Compare node VAL1 with the type VAL2. This function is used by the
hash table abstract_pending_vars. */
-static int
-pat_compare (const void* val1, const void* val2)
+bool
+abstract_type_hasher::equal (pending_abstract_type *pat1, tree type2)
{
- const struct pending_abstract_type *const pat1 =
- (const struct pending_abstract_type *) val1;
- const_tree const type2 = (const_tree)val2;
-
return (pat1->type == type2);
}
/* Hash table that maintains pending_abstract_type nodes, for which we still
need to check for type abstractness. The key of the table is the type
of the declaration. */
-static GTY ((param_is (struct pending_abstract_type)))
-htab_t abstract_pending_vars = NULL;
+static GTY (()) hash_table<abstract_type_hasher> *abstract_pending_vars = NULL;
static int abstract_virtuals_error_sfinae (tree, tree, abstract_class_use, tsubst_flags_t);
@@ -197,7 +196,6 @@ static int abstract_virtuals_error_sfinae (tree, tree, abstract_class_use, tsubs
void
complete_type_check_abstract (tree type)
{
- void **slot;
struct pending_abstract_type *pat;
location_t cur_loc = input_location;
@@ -207,11 +205,12 @@ complete_type_check_abstract (tree type)
return;
/* Retrieve the list of pending declarations for this type. */
- slot = htab_find_slot_with_hash (abstract_pending_vars, type,
- (hashval_t)TYPE_UID (type), NO_INSERT);
+ pending_abstract_type **slot
+ = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
+ NO_INSERT);
if (!slot)
return;
- pat = (struct pending_abstract_type*)*slot;
+ pat = *slot;
gcc_assert (pat);
/* If the type is not abstract, do not do anything. */
@@ -244,7 +243,7 @@ complete_type_check_abstract (tree type)
}
}
- htab_clear_slot (abstract_pending_vars, slot);
+ abstract_pending_vars->clear_slot (slot);
input_location = cur_loc;
}
@@ -282,17 +281,17 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
name. */
if (!COMPLETE_TYPE_P (type) && (complain & tf_error))
{
- void **slot;
struct pending_abstract_type *pat;
gcc_assert (!decl || DECL_P (decl) || identifier_p (decl));
if (!abstract_pending_vars)
- abstract_pending_vars = htab_create_ggc (31, &pat_calc_hash,
- &pat_compare, NULL);
+ abstract_pending_vars
+ = hash_table<abstract_type_hasher>::create_ggc (31);
- slot = htab_find_slot_with_hash (abstract_pending_vars, type,
- (hashval_t)TYPE_UID (type), INSERT);
+ pending_abstract_type **slot
+ = abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
+ INSERT);
pat = ggc_alloc<pending_abstract_type> ();
pat->type = type;
@@ -302,7 +301,7 @@ abstract_virtuals_error_sfinae (tree decl, tree type, abstract_class_use use,
? DECL_SOURCE_LOCATION (decl)
: input_location);
- pat->next = (struct pending_abstract_type *) *slot;
+ pat->next = *slot;
*slot = pat;
return 0;