From 2a22f99cb12d82712dd93cfef808b1cef543601b Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Sun, 12 Oct 2014 22:22:53 +0000 Subject: 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 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/cp-gimplify.c | 14 +++--- gcc/cp/cp-tree.h | 21 ++++++--- gcc/cp/decl.c | 124 +++++++++++++++++++++++---------------------------- gcc/cp/mangle.c | 35 +++++++++------ gcc/cp/name-lookup.c | 11 ++--- gcc/cp/pt.c | 82 +++++++++++++++------------------- gcc/cp/semantics.c | 74 +++++++++++++++--------------- gcc/cp/tree.c | 85 ++++++++++++++++++----------------- gcc/cp/typeck2.c | 47 ++++++++++--------- 10 files changed, 251 insertions(+), 248 deletions(-) (limited to 'gcc/cp') 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 + + * 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 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 +{ + 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 +{ + 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 *x_named_labels; cp_binding_level *bindings; vec *x_local_names; /* Tracking possibly infinite loops. This is a vec only because vec doesn't work with gtype. */ vec *infinite_loops; - htab_t GTY((param_is (struct cxx_int_tree_map))) extern_decl_map; + hash_table *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 (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 + (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::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 (); 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 { - 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_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::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 +{ + 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_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::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::create_ggc (20); h = ggc_alloc (); 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 +{ + 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 *decl_specializations; -static GTY ((param_is (spec_entry))) - htab_t type_specializations; +static GTY (()) hash_table *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 (); *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 *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 (); *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::create_ggc (37); + type_specializations = hash_table::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 +{ + 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_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::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 (); @@ -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 +{ + 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_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::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 +{ + 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_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::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 +{ + 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_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::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 +{ + 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_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::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 (); 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; -- cgit v1.1