+2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
+
+* 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.
+
2014-10-11 Oleg Endo <olegendo@gcc.gnu.org>
* config/sh/sh.h (TARGET_SH4A_ARCH): Remove macro.
/* Called via htab_traverse. Count number of emitted
STRING_CSTs in the constant hash table. */
-static int
-count_string_csts (void **slot, void *data)
+int
+count_string_csts (constant_descriptor_tree **slot,
+ unsigned HOST_WIDE_INT *data)
{
- struct constant_descriptor_tree *desc
- = (struct constant_descriptor_tree *) *slot;
+ struct constant_descriptor_tree *desc = *slot;
if (TREE_CODE (desc->value) == STRING_CST
&& TREE_ASM_WRITTEN (desc->value)
&& asan_protect_global (desc->value))
- ++*((unsigned HOST_WIDE_INT *) data);
+ ++*data;
return 1;
}
vec<constructor_elt, va_gc> *v;
};
-/* Called via htab_traverse. Call asan_add_global
+/* Called via hash_table::traverse. Call asan_add_global
on emitted STRING_CSTs from the constant hash table. */
-static int
-add_string_csts (void **slot, void *data)
+int
+add_string_csts (constant_descriptor_tree **slot,
+ asan_add_string_csts_data *aascd)
{
- struct constant_descriptor_tree *desc
- = (struct constant_descriptor_tree *) *slot;
+ struct constant_descriptor_tree *desc = *slot;
if (TREE_CODE (desc->value) == STRING_CST
&& TREE_ASM_WRITTEN (desc->value)
&& asan_protect_global (desc->value))
{
- struct asan_add_string_csts_data *aascd
- = (struct asan_add_string_csts_data *) data;
asan_add_global (SYMBOL_REF_DECL (XEXP (desc->rtl, 0)),
aascd->type, aascd->v);
}
if (TREE_ASM_WRITTEN (vnode->decl)
&& asan_protect_global (vnode->decl))
++gcount;
- htab_t const_desc_htab = constant_pool_htab ();
- htab_traverse (const_desc_htab, count_string_csts, &gcount);
+ hash_table<tree_descriptor_hasher> *const_desc_htab = constant_pool_htab ();
+ const_desc_htab->traverse<unsigned HOST_WIDE_INT *, count_string_csts>
+ (&gcount);
if (gcount)
{
tree type = asan_global_struct (), var, ctor;
struct asan_add_string_csts_data aascd;
aascd.type = TREE_TYPE (type);
aascd.v = v;
- htab_traverse (const_desc_htab, add_string_csts, &aascd);
+ const_desc_htab->traverse<asan_add_string_csts_data *, add_string_csts>
+ (&aascd);
ctor = build_constructor (type, v);
TREE_CONSTANT (ctor) = 1;
TREE_STATIC (ctor) = 1;
+2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
+
+ * c-common.c: Use hash_table instead of hashtab.
+
2014-10-06 Edward Smith-Rowland <3dw4rd@verizon.net>
* c-family/c-cppbuiltin.c: Move __cpp_attribute_deprecated to the
}
}
+struct c_type_hasher : ggc_hasher<tree>
+{
+ static hashval_t hash (tree);
+ static bool equal (tree, tree);
+};
+
/* Hash function for the problem of multiple type definitions in
different files. This must hash all types that will compare
equal via comptypes to the same value. In practice it hashes
on some of the simple stuff and leaves the details to comptypes. */
-static hashval_t
-c_type_hash (const void *p)
+hashval_t
+c_type_hasher::hash (tree t)
{
int n_elements;
int shift, size;
- const_tree const t = (const_tree) p;
tree t2;
switch (TREE_CODE (t))
{
/* For pointers, hash on pointee type plus some swizzling. */
case POINTER_TYPE:
- return c_type_hash (TREE_TYPE (t)) ^ 0x3003003;
+ return hash (TREE_TYPE (t)) ^ 0x3003003;
/* Hash on number of elements and total size. */
case ENUMERAL_TYPE:
shift = 3;
return ((size << 24) | (n_elements << shift));
}
-static GTY((param_is (union tree_node))) htab_t type_hash_table;
+bool
+c_type_hasher::equal (tree t1, tree t2)
+{
+ return lang_hooks.types_compatible_p (t1, t2);
+}
+
+static GTY(()) hash_table<c_type_hasher> *type_hash_table;
/* Return the typed-based alias set for T, which may be an expression
or a type. Return -1 if we don't do anything special. */
c_common_get_alias_set (tree t)
{
tree u;
- PTR *slot;
/* For VLAs, use the alias set of the element type rather than the
default of alias set 0 for types compared structurally. */
/* Look up t in hash table. Only one of the compatible types within each
alias set is recorded in the table. */
if (!type_hash_table)
- type_hash_table = htab_create_ggc (1021, c_type_hash,
- (htab_eq) lang_hooks.types_compatible_p,
- NULL);
- slot = htab_find_slot (type_hash_table, t, INSERT);
+ type_hash_table = hash_table<c_type_hasher>::create_ggc (1021);
+ tree *slot = type_hash_table->find_slot (t, INSERT);
if (*slot != NULL)
{
TYPE_ALIAS_SET (t) = TYPE_ALIAS_SET ((tree)*slot);
/* Hash function for struct loop_exit. */
-static hashval_t
-loop_exit_hash (const void *ex)
+hashval_t
+loop_exit_hasher::hash (loop_exit *exit)
{
- const struct loop_exit *const exit = (const struct loop_exit *) ex;
-
return htab_hash_pointer (exit->e);
}
/* Equality function for struct loop_exit. Compares with edge. */
-static int
-loop_exit_eq (const void *ex, const void *e)
+bool
+loop_exit_hasher::equal (loop_exit *exit, edge e)
{
- const struct loop_exit *const exit = (const struct loop_exit *) ex;
-
return exit->e == e;
}
/* Frees the list of loop exit descriptions EX. */
-static void
-loop_exit_free (void *ex)
+void
+loop_exit_hasher::remove (loop_exit *exit)
{
- struct loop_exit *exit = (struct loop_exit *) ex, *next;
-
+ loop_exit *next;
for (; exit; exit = next)
{
next = exit->next_e;
static struct loop_exit *
get_exit_descriptions (edge e)
{
- return (struct loop_exit *) htab_find_with_hash (current_loops->exits, e,
- htab_hash_pointer (e));
+ return current_loops->exits->find_with_hash (e, htab_hash_pointer (e));
}
/* Updates the lists of loop exits in that E appears.
void
rescan_loop_exit (edge e, bool new_edge, bool removed)
{
- void **slot;
struct loop_exit *exits = NULL, *exit;
struct loop *aloop, *cloop;
if (!exits && new_edge)
return;
- slot = htab_find_slot_with_hash (current_loops->exits, e,
- htab_hash_pointer (e),
- exits ? INSERT : NO_INSERT);
+ loop_exit **slot
+ = current_loops->exits->find_slot_with_hash (e, htab_hash_pointer (e),
+ exits ? INSERT : NO_INSERT);
if (!slot)
return;
if (exits)
{
if (*slot)
- loop_exit_free (*slot);
+ loop_exit_hasher::remove (*slot);
*slot = exits;
}
else
- htab_clear_slot (current_loops->exits, slot);
+ current_loops->exits->clear_slot (slot);
}
/* For each loop, record list of exit edges, and start maintaining these
loops_state_set (LOOPS_HAVE_RECORDED_EXITS);
gcc_assert (current_loops->exits == NULL);
- current_loops->exits = htab_create_ggc (2 * number_of_loops (cfun),
- loop_exit_hash, loop_exit_eq,
- loop_exit_free);
+ current_loops->exits
+ = hash_table<loop_exit_hasher>::create_ggc (2 * number_of_loops (cfun));
FOR_EACH_BB_FN (bb, cfun)
{
/* Dumps information about the exit in *SLOT to FILE.
Callback for htab_traverse. */
-static int
-dump_recorded_exit (void **slot, void *file)
+int
+dump_recorded_exit (loop_exit **slot, FILE *file)
{
- struct loop_exit *exit = (struct loop_exit *) *slot;
+ struct loop_exit *exit = *slot;
unsigned n = 0;
edge e = exit->e;
for (; exit != NULL; exit = exit->next_e)
n++;
- fprintf ((FILE*) file, "Edge %d->%d exits %u loops\n",
+ fprintf (file, "Edge %d->%d exits %u loops\n",
e->src->index, e->dest->index, n);
return 1;
{
if (!current_loops->exits)
return;
- htab_traverse (current_loops->exits, dump_recorded_exit, file);
+ current_loops->exits->traverse<FILE *, dump_recorded_exit> (file);
}
/* Releases lists of loop exits. */
release_recorded_exits (void)
{
gcc_assert (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS));
- htab_delete (current_loops->exits);
+ current_loops->exits->empty ();
current_loops->exits = NULL;
loops_state_clear (LOOPS_HAVE_RECORDED_EXITS);
}
}
}
- if (n_exits != htab_elements (current_loops->exits))
+ if (n_exits != current_loops->exits->elements ())
{
error ("too many loop exits recorded");
err = 1;
/* Description of the loop exit. */
-struct GTY (()) loop_exit {
+struct GTY ((for_user)) loop_exit {
/* The exit edge. */
edge e;
struct loop_exit *next_e;
};
+struct loop_exit_hasher : ggc_hasher<loop_exit *>
+{
+ typedef edge compare_type;
+
+ static hashval_t hash (loop_exit *);
+ static bool equal (loop_exit *, edge);
+ static void remove (loop_exit *);
+};
+
typedef struct loop *loop_p;
/* An integer estimation of the number of iterations. Estimate_state
/* Maps edges to the list of their descriptions as loop exits. Edges
whose sources or destinations have loop_father == NULL (which may
happen during the cfg manipulations) should not appear in EXITS. */
- htab_t GTY((param_is (struct loop_exit))) exits;
+ hash_table<loop_exit_hasher> *GTY(()) exits;
/* Pointer to root of loop hierarchy tree. */
struct loop *tree_root;
struct cgraph_2node_hook_list *next;
};
+/* Hash descriptor for cgraph_function_version_info. */
+
+struct function_version_hasher : ggc_hasher<cgraph_function_version_info *>
+{
+ static hashval_t hash (cgraph_function_version_info *);
+ static bool equal (cgraph_function_version_info *,
+ cgraph_function_version_info *);
+};
+
/* Map a cgraph_node to cgraph_function_version_info using this htab.
The cgraph_function_version_info has a THIS_NODE field that is the
corresponding cgraph_node.. */
-static GTY((param_is (cgraph_function_version_info))) htab_t
- cgraph_fnver_htab = NULL;
+static GTY(()) hash_table<function_version_hasher> *cgraph_fnver_htab = NULL;
/* Hash function for cgraph_fnver_htab. */
-static hashval_t
-cgraph_fnver_htab_hash (const void *ptr)
+hashval_t
+function_version_hasher::hash (cgraph_function_version_info *ptr)
{
- int uid = ((const cgraph_function_version_info *)ptr)->this_node->uid;
+ int uid = ptr->this_node->uid;
return (hashval_t)(uid);
}
/* eq function for cgraph_fnver_htab. */
-static int
-cgraph_fnver_htab_eq (const void *p1, const void *p2)
+bool
+function_version_hasher::equal (cgraph_function_version_info *n1,
+ cgraph_function_version_info *n2)
{
- const cgraph_function_version_info *n1
- = (const cgraph_function_version_info *)p1;
- const cgraph_function_version_info *n2
- = (const cgraph_function_version_info *)p2;
-
return n1->this_node->uid == n2->this_node->uid;
}
cgraph_function_version_info *
cgraph_node::function_version (void)
{
- cgraph_function_version_info *ret;
cgraph_function_version_info key;
key.this_node = this;
if (cgraph_fnver_htab == NULL)
return NULL;
- ret = (cgraph_function_version_info *)
- htab_find (cgraph_fnver_htab, &key);
-
- return ret;
+ return cgraph_fnver_htab->find (&key);
}
/* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
cgraph_function_version_info *
cgraph_node::insert_new_function_version (void)
{
- void **slot;
-
version_info_node = NULL;
version_info_node = ggc_cleared_alloc<cgraph_function_version_info> ();
version_info_node->this_node = this;
if (cgraph_fnver_htab == NULL)
- cgraph_fnver_htab = htab_create_ggc (2, cgraph_fnver_htab_hash,
- cgraph_fnver_htab_eq, NULL);
+ cgraph_fnver_htab = hash_table<function_version_hasher>::create_ggc (2);
- slot = htab_find_slot (cgraph_fnver_htab, version_info_node, INSERT);
- gcc_assert (slot != NULL);
- *slot = version_info_node;
+ *cgraph_fnver_htab->find_slot (version_info_node, INSERT)
+ = version_info_node;
return version_info_node;
}
decl_v->next->prev = decl_v->prev;
if (cgraph_fnver_htab != NULL)
- htab_remove_elt (cgraph_fnver_htab, decl_v);
+ cgraph_fnver_htab->remove_elt (decl_v);
decl_node->remove ();
}
/* Returns a hash value for X (which really is a cgraph_edge). */
-static hashval_t
-edge_hash (const void *x)
+hashval_t
+cgraph_edge_hasher::hash (cgraph_edge *e)
{
- return htab_hash_pointer (((const cgraph_edge *) x)->call_stmt);
+ return htab_hash_pointer (e->call_stmt);
}
/* Return nonzero if the call_stmt of of cgraph_edge X is stmt *Y. */
-static int
-edge_eq (const void *x, const void *y)
+inline bool
+cgraph_edge_hasher::equal (cgraph_edge *x, gimple y)
{
- return ((const cgraph_edge *) x)->call_stmt == y;
+ return x->call_stmt == y;
}
/* Add call graph edge E to call site hash of its caller. */
static inline void
cgraph_update_edge_in_call_site_hash (cgraph_edge *e)
{
- void **slot;
- slot = htab_find_slot_with_hash (e->caller->call_site_hash,
- e->call_stmt,
- htab_hash_pointer (e->call_stmt),
- INSERT);
- *slot = e;
+ gimple call = e->call_stmt;
+ *e->caller->call_site_hash->find_slot_with_hash (call,
+ htab_hash_pointer (call),
+ INSERT) = e;
}
/* Add call graph edge E to call site hash of its caller. */
static inline void
cgraph_add_edge_to_call_site_hash (cgraph_edge *e)
{
- void **slot;
/* There are two speculative edges for every statement (one direct,
one indirect); always hash the direct one. */
if (e->speculative && e->indirect_unknown_callee)
return;
- slot = htab_find_slot_with_hash (e->caller->call_site_hash,
- e->call_stmt,
- htab_hash_pointer (e->call_stmt),
- INSERT);
+ cgraph_edge **slot = e->caller->call_site_hash->find_slot_with_hash
+ (e->call_stmt,
+ htab_hash_pointer (e->call_stmt), INSERT);
if (*slot)
{
gcc_assert (((cgraph_edge *)*slot)->speculative);
int n = 0;
if (call_site_hash)
- return (cgraph_edge *)
- htab_find_with_hash (call_site_hash, call_stmt,
- htab_hash_pointer (call_stmt));
+ return call_site_hash->find_with_hash (call_stmt,
+ htab_hash_pointer (call_stmt));
/* This loop may turn out to be performance problem. In such case adding
hashtables into call nodes with very many edges is probably best
if (n > 100)
{
- call_site_hash = htab_create_ggc (120, edge_hash, edge_eq, NULL);
+ call_site_hash = hash_table<cgraph_edge_hasher>::create_ggc (120);
for (e2 = callees; e2; e2 = e2->next_callee)
cgraph_add_edge_to_call_site_hash (e2);
for (e2 = indirect_calls; e2; e2 = e2->next_callee)
if (caller->call_site_hash
&& (!speculative || !indirect_unknown_callee))
{
- htab_remove_elt_with_hash (caller->call_site_hash,
- call_stmt,
- htab_hash_pointer (call_stmt));
+ caller->call_site_hash->remove_elt_with_hash
+ (call_stmt, htab_hash_pointer (call_stmt));
}
cgraph_edge *e = this;
caller->callees = next_callee;
}
if (caller->call_site_hash)
- htab_remove_elt_with_hash (caller->call_site_hash,
- call_stmt,
- htab_hash_pointer (call_stmt));
+ caller->call_site_hash->remove_elt_with_hash (call_stmt,
+ htab_hash_pointer (call_stmt));
}
/* Put the edge onto the free list. */
callees = NULL;
if (call_site_hash)
{
- htab_delete (call_site_hash);
+ call_site_hash->empty ();
call_site_hash = NULL;
}
}
decl = NULL;
if (call_site_hash)
{
- htab_delete (call_site_hash);
+ call_site_hash->empty ();
call_site_hash = NULL;
}
/* Section names are stored as reference counted strings in GGC safe hashtable
(to make them survive through PCH). */
-struct GTY(()) section_hash_entry_d
+struct GTY((for_user)) section_hash_entry_d
{
int ref_count;
char *name; /* As long as this datastructure stays in GGC, we can not put
typedef struct section_hash_entry_d section_hash_entry;
+struct section_name_hasher : ggc_hasher<section_hash_entry *>
+{
+ typedef const char *compare_type;
+
+ static hashval_t hash (section_hash_entry *);
+ static bool equal (section_hash_entry *, const char *);
+};
+
enum availability
{
/* Not yet set by cgraph_function_body_availability. */
};
/* Function Multiversioning info. */
-struct GTY(()) cgraph_function_version_info {
+struct GTY((for_user)) cgraph_function_version_info {
/* The cgraph_node for which the function version info is stored. */
cgraph_node *this_node;
/* Chains all the semantically identical function versions. The
struct cgraph_edge;
+struct cgraph_edge_hasher : ggc_hasher<cgraph_edge *>
+{
+ typedef gimple compare_type;
+
+ static hashval_t hash (cgraph_edge *);
+ static bool equal (cgraph_edge *, gimple);
+};
+
/* The cgraph data structure.
Each function decl has assigned cgraph_node listing callees and callers. */
cgraph_node *clone_of;
/* For functions with many calls sites it holds map from call expression
to the edge to speed up cgraph_edge function. */
- htab_t GTY((param_is (cgraph_edge))) call_site_hash;
+ hash_table<cgraph_edge_hasher> *GTY(()) call_site_hash;
/* Declaration node used to be clone of. */
tree former_clone_of;
unsigned vptr_changed : 1;
};
-struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge {
+struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"),
+ for_user)) cgraph_edge {
friend class cgraph_node;
/* Remove the edge in the cgraph. */
FINISHED
};
+struct asmname_hasher
+{
+ typedef symtab_node *value_type;
+ typedef const_tree compare_type;
+ typedef int store_values_directly;
+
+ static hashval_t hash (symtab_node *n);
+ static bool equal (symtab_node *n, const_tree t);
+ static void ggc_mx (symtab_node *n);
+ static void pch_nx (symtab_node *&);
+ static void pch_nx (symtab_node *&, gt_pointer_operator, void *);
+ static void remove (symtab_node *) {}
+};
+
class GTY((tag ("SYMTAB"))) symbol_table
{
public:
bool cpp_implicit_aliases_done;
/* Hash table used to hold sectoons. */
- htab_t GTY((param_is (section_hash_entry))) section_hash;
+ hash_table<section_name_hasher> *GTY(()) section_hash;
/* Hash table used to convert assembler names into nodes. */
- htab_t GTY((param_is (symtab_node))) assembler_name_hash;
+ hash_table<asmname_hasher> *assembler_name_hash;
/* Hash table used to hold init priorities. */
hash_map<symtab_node *, symbol_priority_map> *init_priority_hash;
/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
static bool decl_assembler_name_equal (tree decl, const_tree asmname);
- /* Returns a hash code for P. */
- static hashval_t hash_node_by_assembler_name (const void *p);
-
- /* Returns nonzero if P1 and P2 are equal. */
- static int eq_assembler_name (const void *p1, const void *p2);
+ friend struct asmname_hasher;
/* List of hooks triggered when an edge is removed. */
cgraph_edge_hook_list * GTY((skip)) m_first_edge_removal_hook;
extern vec<cgraph_node *> cgraph_new_nodes;
+inline hashval_t
+asmname_hasher::hash (symtab_node *n)
+{
+ return symbol_table::decl_assembler_name_hash
+ (DECL_ASSEMBLER_NAME (n->decl));
+}
+
+inline bool
+asmname_hasher::equal (symtab_node *n, const_tree t)
+{
+ return symbol_table::decl_assembler_name_equal (n->decl, t);
+}
+
+extern void gt_ggc_mx (symtab_node *&);
+
+inline void
+asmname_hasher::ggc_mx (symtab_node *n)
+{
+ gt_ggc_mx (n);
+}
+
+extern void gt_pch_nx (symtab_node *&);
+
+inline void
+asmname_hasher::pch_nx (symtab_node *&n)
+{
+ gt_pch_nx (n);
+}
+
+inline void
+asmname_hasher::pch_nx (symtab_node *&n, gt_pointer_operator op, void *cookie)
+{
+ op (&n, cookie);
+}
+
/* In cgraph.c */
void release_function_body (tree);
cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
Each constant in memory thus far output is recorded
in `const_desc_table'. */
-struct GTY(()) constant_descriptor_tree {
+struct GTY((for_user)) constant_descriptor_tree {
/* A MEM for the constant. */
rtx rtl;
&& !force_output);
}
+struct tree_descriptor_hasher : ggc_hasher<constant_descriptor_tree *>
+{
+ static hashval_t hash (constant_descriptor_tree *);
+ static bool equal (constant_descriptor_tree *, constant_descriptor_tree *);
+};
+
/* Constant pool accessor function. */
-htab_t constant_pool_htab (void);
+hash_table<tree_descriptor_hasher> *constant_pool_htab (void);
/* Return node that alias is aliasing. */
/* The suffix attached to stub symbols. */
#define STUB_SUFFIX "$stub"
-typedef struct GTY (()) machopic_indirection
+typedef struct GTY ((for_user)) machopic_indirection
{
/* The SYMBOL_REF for the entity referenced. */
rtx symbol;
bool used;
} machopic_indirection;
+struct indirection_hasher : ggc_hasher<machopic_indirection *>
+{
+ typedef const char *compare_type;
+ static hashval_t hash (machopic_indirection *);
+ static bool equal (machopic_indirection *, const char *);
+};
+
/* A table mapping stub names and non-lazy pointer names to
SYMBOL_REFs for the stubbed-to and pointed-to entities. */
-static GTY ((param_is (struct machopic_indirection))) htab_t
- machopic_indirections;
+static GTY (()) hash_table<indirection_hasher> *machopic_indirections;
/* Return a hash value for a SLOT in the indirections hash table. */
-static hashval_t
-machopic_indirection_hash (const void *slot)
+hashval_t
+indirection_hasher::hash (machopic_indirection *p)
{
- const machopic_indirection *p = (const machopic_indirection *) slot;
return htab_hash_string (p->ptr_name);
}
/* Returns true if the KEY is the same as that associated with
SLOT. */
-static int
-machopic_indirection_eq (const void *slot, const void *key)
+bool
+indirection_hasher::equal (machopic_indirection *s, const char *k)
{
- return strcmp (((const machopic_indirection *) slot)->ptr_name,
- (const char *) key) == 0;
+ return strcmp (s->ptr_name, k) == 0;
}
/* Return the name of the non-lazy pointer (if STUB_P is false) or
const char *name = XSTR (sym_ref, 0);
size_t namelen = strlen (name);
machopic_indirection *p;
- void ** slot;
bool needs_quotes;
const char *suffix;
const char *prefix = user_label_prefix;
sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
if (!machopic_indirections)
- machopic_indirections = htab_create_ggc (37,
- machopic_indirection_hash,
- machopic_indirection_eq,
- /*htab_del=*/NULL);
+ machopic_indirections = hash_table<indirection_hasher>::create_ggc (37);
- slot = htab_find_slot_with_hash (machopic_indirections, buffer,
- htab_hash_string (buffer), INSERT);
+ machopic_indirection **slot
+ = machopic_indirections->find_slot_with_hash (buffer,
+ htab_hash_string (buffer),
+ INSERT);
if (*slot)
{
- p = (machopic_indirection *) *slot;
+ p = *slot;
}
else
{
void
machopic_validate_stub_or_non_lazy_ptr (const char *name)
{
- machopic_indirection *p;
-
- p = ((machopic_indirection *)
- (htab_find_with_hash (machopic_indirections, name,
- htab_hash_string (name))));
+ machopic_indirection *p
+ = machopic_indirections->find_with_hash (name, htab_hash_string (name));
if (p && ! p->used)
{
const char *real_name;
DATA is the FILE* for assembly output. Called from
htab_traverse. */
-static int
-machopic_output_indirection (void **slot, void *data)
+int
+machopic_output_indirection (machopic_indirection **slot, FILE *asm_out_file)
{
- machopic_indirection *p = *((machopic_indirection **) slot);
- FILE *asm_out_file = (FILE *) data;
+ machopic_indirection *p = *slot;
rtx symbol;
const char *sym_name;
const char *ptr_name;
machopic_finish (FILE *asm_out_file)
{
if (machopic_indirections)
- htab_traverse_noresize (machopic_indirections,
- machopic_output_indirection,
- asm_out_file);
+ machopic_indirections
+ ->traverse_noresize<FILE *, machopic_output_indirection> (asm_out_file);
}
int
/* Store all constructed constant CFStrings in a hash table so that
they get uniqued properly. */
-typedef struct GTY (()) cfstring_descriptor {
+typedef struct GTY ((for_user)) cfstring_descriptor {
/* The string literal. */
tree literal;
/* The resulting constant CFString. */
tree constructor;
} cfstring_descriptor;
-static GTY ((param_is (struct cfstring_descriptor))) htab_t cfstring_htab;
+struct cfstring_hasher : ggc_hasher<cfstring_descriptor *>
+{
+ static hashval_t hash (cfstring_descriptor *);
+ static bool equal (cfstring_descriptor *, cfstring_descriptor *);
+};
-static hashval_t cfstring_hash (const void *);
-static int cfstring_eq (const void *, const void *);
+static GTY (()) hash_table<cfstring_hasher> *cfstring_htab;
static tree
add_builtin_field_decl (tree type, const char *name, tree **chain)
rest_of_decl_compilation (cfstring_class_reference, 0, 0);
/* Initialize the hash table used to hold the constant CFString objects. */
- cfstring_htab = htab_create_ggc (31, cfstring_hash, cfstring_eq, NULL);
+ cfstring_htab = hash_table<cfstring_hasher>::create_ggc (31);
return cfstring_type_node;
}
return true;
}
-static hashval_t
-cfstring_hash (const void *ptr)
+hashval_t
+cfstring_hasher::hash (cfstring_descriptor *ptr)
{
- tree str = ((const struct cfstring_descriptor *)ptr)->literal;
+ tree str = ptr->literal;
const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
int i, len = TREE_STRING_LENGTH (str);
hashval_t h = len;
return h;
}
-static int
-cfstring_eq (const void *ptr1, const void *ptr2)
+bool
+cfstring_hasher::equal (cfstring_descriptor *ptr1, cfstring_descriptor *ptr2)
{
- tree str1 = ((const struct cfstring_descriptor *)ptr1)->literal;
- tree str2 = ((const struct cfstring_descriptor *)ptr2)->literal;
+ tree str1 = ptr1->literal;
+ tree str2 = ptr2->literal;
int len1 = TREE_STRING_LENGTH (str1);
return (len1 == TREE_STRING_LENGTH (str2)
darwin_build_constant_cfstring (tree str)
{
struct cfstring_descriptor *desc, key;
- void **loc;
tree addr;
if (!str)
/* Perhaps we already constructed a constant CFString just like this one? */
key.literal = str;
- loc = htab_find_slot (cfstring_htab, &key, INSERT);
- desc = (struct cfstring_descriptor *) *loc;
+ cfstring_descriptor **loc = cfstring_htab->find_slot (&key, INSERT);
+ desc = *loc;
if (!desc)
{
darwin_cfstring_p (tree str)
{
struct cfstring_descriptor key;
- void **loc;
if (!str)
return false;
return false;
key.literal = str;
- loc = htab_find_slot (cfstring_htab, &key, NO_INSERT);
+ cfstring_descriptor **loc = cfstring_htab->find_slot (&key, NO_INSERT);
if (loc)
return true;
darwin_enter_string_into_cfstring_table (tree str)
{
struct cfstring_descriptor key;
- void **loc;
key.literal = str;
- loc = htab_find_slot (cfstring_htab, &key, INSERT);
+ cfstring_descriptor **loc = cfstring_htab->find_slot (&key, INSERT);
if (!*loc)
{
}
-struct GTY(()) pragma_entry {
- const char *varname;
- unsigned address;
+struct pragma_traits : default_hashmap_traits
+{
+ static hashval_t hash (const char *str) { return htab_hash_string (str); }
+ static bool
+ equal_keys (const char *a, const char *b)
+ {
+ return !strcmp (a, b);
+ }
};
-typedef struct pragma_entry pragma_entry;
/* Hash table of pragma info. */
-static GTY((param_is (pragma_entry))) htab_t pragma_htab;
-
-static int
-pragma_entry_eq (const void *p1, const void *p2)
-{
- const pragma_entry *old = (const pragma_entry *) p1;
- const char *new_name = (const char *) p2;
-
- return strcmp (old->varname, new_name) == 0;
-}
-
-static hashval_t
-pragma_entry_hash (const void *p)
-{
- const pragma_entry *old = (const pragma_entry *) p;
- return htab_hash_string (old->varname);
-}
+static GTY(()) hash_map<const char *, unsigned, pragma_traits> *pragma_htab;
void
m32c_note_pragma_address (const char *varname, unsigned address)
{
- pragma_entry **slot;
-
if (!pragma_htab)
- pragma_htab = htab_create_ggc (31, pragma_entry_hash,
- pragma_entry_eq, NULL);
+ pragma_htab
+ = hash_map<const char *, unsigned, pragma_traits>::create_ggc (31);
- slot = (pragma_entry **)
- htab_find_slot_with_hash (pragma_htab, varname,
- htab_hash_string (varname), INSERT);
-
- if (!*slot)
- {
- *slot = ggc_alloc<pragma_entry> ();
- (*slot)->varname = ggc_strdup (varname);
- }
- (*slot)->address = address;
+ const char *name = ggc_strdup (varname);
+ unsigned int *slot = &pragma_htab->get_or_insert (name);
+ *slot = address;
}
static bool
m32c_get_pragma_address (const char *varname, unsigned *address)
{
- pragma_entry **slot;
-
if (!pragma_htab)
return false;
- slot = (pragma_entry **)
- htab_find_slot_with_hash (pragma_htab, varname,
- htab_hash_string (varname), NO_INSERT);
- if (slot && *slot)
+ unsigned int *slot = pragma_htab->get (varname);
+ if (slot)
{
- *address = (*slot)->address;
+ *address = *slot;
return true;
}
return false;
struct GTY(()) pragma_entry {
int used;
int flag;
- const char *funcname;
};
-typedef struct pragma_entry pragma_entry;
-/* Hash table of farcall-tagged sections. */
-static GTY((param_is (pragma_entry))) htab_t pragma_htab;
-
-static int
-pragma_entry_eq (const void *p1, const void *p2)
+struct pragma_traits : default_hashmap_traits
{
- const pragma_entry *old = (const pragma_entry *) p1;
- const char *new_name = (const char *) p2;
-
- return strcmp (old->funcname, new_name) == 0;
-}
+ static hashval_t hash (const char *s) { return htab_hash_string (s); }
+ static bool
+ equal_keys (const char *a, const char *b)
+ {
+ return strcmp (a, b) == 0;
+ }
+};
-static hashval_t
-pragma_entry_hash (const void *p)
-{
- const pragma_entry *old = (const pragma_entry *) p;
- return htab_hash_string (old->funcname);
-}
+/* Hash table of farcall-tagged sections. */
+static GTY(()) hash_map<const char *, pragma_entry, pragma_traits> *
+ pragma_htab;
static void
mep_note_pragma_flag (const char *funcname, int flag)
{
- pragma_entry **slot;
-
if (!pragma_htab)
- pragma_htab = htab_create_ggc (31, pragma_entry_hash,
- pragma_entry_eq, NULL);
-
- slot = (pragma_entry **)
- htab_find_slot_with_hash (pragma_htab, funcname,
- htab_hash_string (funcname), INSERT);
+ pragma_htab
+ = hash_map<const char *, pragma_entry, pragma_traits>::create_ggc (31);
- if (!*slot)
+ bool existed;
+ const char *name = ggc_strdup (funcname);
+ pragma_entry *slot = &pragma_htab->get_or_insert (name, &existed);
+ if (!existed)
{
- *slot = ggc_alloc<pragma_entry> ();
- (*slot)->flag = 0;
- (*slot)->used = 0;
- (*slot)->funcname = ggc_strdup (funcname);
+ slot->flag = 0;
+ slot->used = 0;
}
- (*slot)->flag |= flag;
+ slot->flag |= flag;
}
static bool
mep_lookup_pragma_flag (const char *funcname, int flag)
{
- pragma_entry **slot;
-
if (!pragma_htab)
return false;
if (funcname[0] == '@' && funcname[2] == '.')
funcname += 3;
- slot = (pragma_entry **)
- htab_find_slot_with_hash (pragma_htab, funcname,
- htab_hash_string (funcname), NO_INSERT);
- if (slot && *slot && ((*slot)->flag & flag))
+ pragma_entry *slot = pragma_htab->get (funcname);
+ if (slot && (slot->flag & flag))
{
- (*slot)->used |= flag;
+ slot->used |= flag;
return true;
}
return false;
mep_note_pragma_flag (funcname, FUNC_DISINTERRUPT);
}
-static int
-note_unused_pragma_disinterrupt (void **slot, void *data ATTRIBUTE_UNUSED)
+bool
+note_unused_pragma_disinterrupt (const char *const &s, const pragma_entry &e,
+ void *)
{
- const pragma_entry *d = (const pragma_entry *)(*slot);
-
- if ((d->flag & FUNC_DISINTERRUPT)
- && !(d->used & FUNC_DISINTERRUPT))
- warning (0, "\"#pragma disinterrupt %s\" not used", d->funcname);
+ if ((e.flag & FUNC_DISINTERRUPT)
+ && !(e.used & FUNC_DISINTERRUPT))
+ warning (0, "\"#pragma disinterrupt %s\" not used", s);
return 1;
}
mep_file_cleanups (void)
{
if (pragma_htab)
- htab_traverse (pragma_htab, note_unused_pragma_disinterrupt, NULL);
+ pragma_htab->traverse<void *, note_unused_pragma_disinterrupt> (NULL);
}
/* These three functions provide a bridge between the pramgas that
reg_class_t);
static unsigned int mips_function_arg_boundary (enum machine_mode, const_tree);
\f
-/* This hash table keeps track of implicit "mips16" and "nomips16" attributes
- for -mflip_mips16. It maps decl names onto a boolean mode setting. */
-struct GTY (()) mflip_mips16_entry {
- const char *name;
- bool mips16_p;
-};
-static GTY ((param_is (struct mflip_mips16_entry))) htab_t mflip_mips16_htab;
-
-/* Hash table callbacks for mflip_mips16_htab. */
-
-static hashval_t
-mflip_mips16_htab_hash (const void *entry)
+struct mips16_flip_traits : default_hashmap_traits
{
- return htab_hash_string (((const struct mflip_mips16_entry *) entry)->name);
-}
+ static hashval_t hash (const char *s) { return htab_hash_string (s); }
+ static bool
+ equal_keys (const char *a, const char *b)
+ {
+ return !strcmp (a, b);
+ }
+};
-static int
-mflip_mips16_htab_eq (const void *entry, const void *name)
-{
- return strcmp (((const struct mflip_mips16_entry *) entry)->name,
- (const char *) name) == 0;
-}
+/* This hash table keeps track of implicit "mips16" and "nomips16" attributes
+ for -mflip_mips16. It maps decl names onto a boolean mode setting. */
+static GTY (()) hash_map<const char *, bool, mips16_flip_traits> *
+ mflip_mips16_htab;
/* True if -mflip-mips16 should next add an attribute for the default MIPS16
mode, false if it should next add an attribute for the opposite mode. */
static bool
mflip_mips16_use_mips16_p (tree decl)
{
- struct mflip_mips16_entry *entry;
const char *name;
- hashval_t hash;
- void **slot;
bool base_is_mips16 = (mips_base_compression_flags & MASK_MIPS16) != 0;
/* Use the opposite of the command-line setting for anonymous decls. */
return !base_is_mips16;
if (!mflip_mips16_htab)
- mflip_mips16_htab = htab_create_ggc (37, mflip_mips16_htab_hash,
- mflip_mips16_htab_eq, NULL);
+ mflip_mips16_htab
+ = hash_map<const char *, bool, mips16_flip_traits>::create_ggc (37);
name = IDENTIFIER_POINTER (DECL_NAME (decl));
- hash = htab_hash_string (name);
- slot = htab_find_slot_with_hash (mflip_mips16_htab, name, hash, INSERT);
- entry = (struct mflip_mips16_entry *) *slot;
- if (!entry)
+
+ bool existed;
+ bool *slot = &mflip_mips16_htab->get_or_insert (name, &existed);
+ if (!existed)
{
mips16_flipper = !mips16_flipper;
- entry = ggc_alloc<mflip_mips16_entry> ();
- entry->name = name;
- entry->mips16_p = mips16_flipper ? !base_is_mips16 : base_is_mips16;
- *slot = entry;
+ *slot = mips16_flipper ? !base_is_mips16 : base_is_mips16;
}
- return entry->mips16_p;
+ return *slot;
}
\f
/* Predicates to test for presence of "near" and "far"/"long_call"
}
}
\f
+struct local_alias_traits : default_hashmap_traits
+{
+ static hashval_t hash (rtx);
+ static bool equal_keys (rtx, rtx);
+};
+
/* Each locally-defined hard-float MIPS16 function has a local symbol
associated with it. This hash table maps the function symbol (FUNC)
to the local symbol (LOCAL). */
-struct GTY(()) mips16_local_alias {
- rtx func;
- rtx local;
-};
-static GTY ((param_is (struct mips16_local_alias))) htab_t mips16_local_aliases;
+static GTY (()) hash_map<rtx, rtx, local_alias_traits> *mips16_local_aliases;
/* Hash table callbacks for mips16_local_aliases. */
-static hashval_t
-mips16_local_aliases_hash (const void *entry)
+hashval_t
+local_alias_traits::hash (rtx func)
{
- const struct mips16_local_alias *alias;
-
- alias = (const struct mips16_local_alias *) entry;
- return htab_hash_string (XSTR (alias->func, 0));
+ return htab_hash_string (XSTR (func, 0));
}
-static int
-mips16_local_aliases_eq (const void *entry1, const void *entry2)
+bool
+local_alias_traits::equal_keys (rtx func1, rtx func2)
{
- const struct mips16_local_alias *alias1, *alias2;
-
- alias1 = (const struct mips16_local_alias *) entry1;
- alias2 = (const struct mips16_local_alias *) entry2;
- return rtx_equal_p (alias1->func, alias2->func);
+ return rtx_equal_p (func1, func2);
}
/* FUNC is the symbol for a locally-defined hard-float MIPS16 function.
static rtx
mips16_local_alias (rtx func)
{
- struct mips16_local_alias *alias, tmp_alias;
- void **slot;
-
/* Create the hash table if this is the first call. */
if (mips16_local_aliases == NULL)
- mips16_local_aliases = htab_create_ggc (37, mips16_local_aliases_hash,
- mips16_local_aliases_eq, NULL);
+ mips16_local_aliases
+ = hash_map<rtx, rtx, local_alias_traits>::create_ggc (37);
/* Look up the function symbol, creating a new entry if need be. */
- tmp_alias.func = func;
- slot = htab_find_slot (mips16_local_aliases, &tmp_alias, INSERT);
+ bool existed;
+ rtx *slot = &mips16_local_aliases->get_or_insert (func, &existed);
gcc_assert (slot != NULL);
- alias = (struct mips16_local_alias *) *slot;
- if (alias == NULL)
+ if (!existed)
{
const char *func_name, *local_name;
rtx local;
SYMBOL_REF_FLAGS (local) = SYMBOL_REF_FLAGS (func) | SYMBOL_FLAG_LOCAL;
/* Create a new structure to represent the mapping. */
- alias = ggc_alloc<struct mips16_local_alias> ();
- alias->func = func;
- alias->local = local;
- *slot = alias;
+ *slot = local;
}
- return alias->local;
+ return *slot;
}
\f
/* A chained list of functions for which mips16_build_call_stub has already
/* Hash table stuff for keeping track of TOC entries. */
-struct GTY(()) toc_hash_struct
+struct GTY((for_user)) toc_hash_struct
{
/* `key' will satisfy CONSTANT_P; in fact, it will satisfy
ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
int labelno;
};
-static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
+struct toc_hasher : ggc_hasher<toc_hash_struct *>
+{
+ static hashval_t hash (toc_hash_struct *);
+ static bool equal (toc_hash_struct *, toc_hash_struct *);
+};
+
+static GTY (()) hash_table<toc_hasher> *toc_hash_table;
/* Hash table to keep track of the argument types for builtin functions. */
-struct GTY(()) builtin_hash_struct
+struct GTY((for_user)) builtin_hash_struct
{
tree type;
enum machine_mode mode[4]; /* return value + 3 arguments. */
unsigned char uns_p[4]; /* and whether the types are unsigned. */
};
-static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
+struct builtin_hasher : ggc_hasher<builtin_hash_struct *>
+{
+ static hashval_t hash (builtin_hash_struct *);
+ static bool equal (builtin_hash_struct *, builtin_hash_struct *);
+};
+
+static GTY (()) hash_table<builtin_hasher> *builtin_hash_table;
\f
/* Default register names. */
/* Hash function for builtin functions with up to 3 arguments and a return
type. */
-static unsigned
-builtin_hash_function (const void *hash_entry)
+hashval_t
+builtin_hasher::hash (builtin_hash_struct *bh)
{
unsigned ret = 0;
int i;
- const struct builtin_hash_struct *bh =
- (const struct builtin_hash_struct *) hash_entry;
for (i = 0; i < 4; i++)
{
}
/* Compare builtin hash entries H1 and H2 for equivalence. */
-static int
-builtin_hash_eq (const void *h1, const void *h2)
+bool
+builtin_hasher::equal (builtin_hash_struct *p1, builtin_hash_struct *p2)
{
- const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
- const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
-
return ((p1->mode[0] == p2->mode[0])
&& (p1->mode[1] == p2->mode[1])
&& (p1->mode[2] == p2->mode[2])
{
struct builtin_hash_struct h;
struct builtin_hash_struct *h2;
- void **found;
int num_args = 3;
int i;
tree ret_type = NULL_TREE;
/* Create builtin_hash_table. */
if (builtin_hash_table == NULL)
- builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
- builtin_hash_eq, NULL);
+ builtin_hash_table = hash_table<builtin_hasher>::create_ggc (1500);
h.type = NULL_TREE;
h.mode[0] = mode_ret;
GET_MODE_NAME (m));
}
- found = htab_find_slot (builtin_hash_table, &h, INSERT);
+ builtin_hash_struct **found = builtin_hash_table->find_slot (&h, INSERT);
if (*found == NULL)
{
h2 = ggc_alloc<builtin_hash_struct> ();
*h2 = h;
- *found = (void *)h2;
+ *found = h2;
h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
arg_type[2], NULL_TREE);
}
- return ((struct builtin_hash_struct *)(*found))->type;
+ return (*found)->type;
}
static void
return result;
}
-static unsigned
-toc_hash_function (const void *hash_entry)
+hashval_t
+toc_hasher::hash (toc_hash_struct *thc)
{
- const struct toc_hash_struct *thc =
- (const struct toc_hash_struct *) hash_entry;
return rs6000_hash_constant (thc->key) ^ thc->key_mode;
}
/* Compare H1 and H2 for equivalence. */
-static int
-toc_hash_eq (const void *h1, const void *h2)
+bool
+toc_hasher::equal (toc_hash_struct *h1, toc_hash_struct *h2)
{
- rtx r1 = ((const struct toc_hash_struct *) h1)->key;
- rtx r2 = ((const struct toc_hash_struct *) h2)->key;
+ rtx r1 = h1->key;
+ rtx r2 = h2->key;
- if (((const struct toc_hash_struct *) h1)->key_mode
- != ((const struct toc_hash_struct *) h2)->key_mode)
+ if (h1->key_mode != h2->key_mode)
return 0;
return rtx_equal_p (r1, r2);
if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
{
struct toc_hash_struct *h;
- void * * found;
/* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
time because GGC is not initialized at that point. */
if (toc_hash_table == NULL)
- toc_hash_table = htab_create_ggc (1021, toc_hash_function,
- toc_hash_eq, NULL);
+ toc_hash_table = hash_table<toc_hasher>::create_ggc (1021);
h = ggc_alloc<toc_hash_struct> ();
h->key = x;
h->key_mode = mode;
h->labelno = labelno;
- found = htab_find_slot (toc_hash_table, h, INSERT);
+ toc_hash_struct **found = toc_hash_table->find_slot (h, INSERT);
if (*found == NULL)
*found = h;
else /* This is indeed a duplicate.
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
fprintf (file, "%d,", labelno);
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
- fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
- found)->labelno));
+ fprintf (file, "%d\n", ((*found)->labelno));
#ifdef HAVE_AS_TLS
if (TARGET_XCOFF && GET_CODE (x) == SYMBOL_REF
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM");
fprintf (file, "%d,", labelno);
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM");
- fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
- found)->labelno));
+ fprintf (file, "%d\n", ((*found)->labelno));
}
#endif
return;
+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
/* 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. */
{
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;
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. */
/* 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. */
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "tree-hasher.h"
#include "stringpool.h"
#include "stor-layout.h"
#include "varasm.h"
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);
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;
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);
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;
}
{
if (named_labels)
{
- htab_traverse (named_labels, pop_labels_1, block);
+ named_labels->traverse<tree, pop_labels_1> (block);
named_labels = NULL;
}
}
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++.
/* 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)
/* 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.
\f
/* 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. */
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);
/* 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
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;
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. */
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
return r;
}
\f
-/* 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,
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;
^ 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. */
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "tree-hasher.h"
#include "stor-layout.h"
#include "stringpool.h"
#include "tm_p.h"
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
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;
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)
/* 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
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 *);
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;
{
spec_entry *found;
spec_entry elt;
- htab_t specializations;
+ hash_table<spec_hasher> *specializations;
elt.tmpl = tmpl;
elt.args = args;
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;
}
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))
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
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;
/* 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);
}
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);
{
tree templ = NULL_TREE, parmlist;
tree t;
- void **slot;
+ spec_entry **slot;
spec_entry *entry;
spec_entry elt;
hashval_t hash;
/* 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;
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;
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,
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. */
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"
/* 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);
}
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
/* 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> ();
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
/* 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;
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. */
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)
{
#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)
/* 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. */
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);
}
/* 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);
void
complete_type_check_abstract (tree type)
{
- void **slot;
struct pending_abstract_type *pat;
location_t cur_loc = input_location;
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. */
}
}
- htab_clear_slot (abstract_pending_vars, slot);
+ abstract_pending_vars->clear_slot (slot);
input_location = cur_loc;
}
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;
? DECL_SOURCE_LOCATION (decl)
: input_location);
- pat->next = (struct pending_abstract_type *) *slot;
+ pat->next = *slot;
*slot = pat;
return 0;
This is somewhat dangerous; the only safe use is in a union when one
field really isn't ever used.
+@findex for_user
+Use this to mark types that need to be marked by user gc routines, but are not
+refered to in a template argument. So if you have some user gc type T1 and a
+non user gc type T2 you can give T2 the for_user option so that the marking
+functions for T1 can call non mangled functions to mark T2.
+
@findex desc
@findex tag
@findex default
static GTY(()) vec<dw_fde_ref, va_gc> *fde_vec;
-struct GTY(()) indirect_string_node {
+struct GTY((for_user)) indirect_string_node {
const char *str;
unsigned int refcount;
enum dwarf_form form;
unsigned int index;
};
-static GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash;
+struct indirect_string_hasher : ggc_hasher<indirect_string_node *>
+{
+ typedef const char *compare_type;
+
+ static hashval_t hash (indirect_string_node *);
+ static bool equal (indirect_string_node *, const char *);
+};
+
+static GTY (()) hash_table<indirect_string_hasher> *debug_str_hash;
/* With split_debug_info, both the comp_dir and dwo_name go in the
main object file, rather than the dwo, similar to the force_direct
main object file. This limits the complexity to just the places
that need it. */
-static GTY ((param_is (struct indirect_string_node)))
- htab_t skeleton_debug_str_hash;
+static GTY (()) hash_table<indirect_string_hasher> *skeleton_debug_str_hash;
static GTY(()) int dw2_string_counter;
for emitting location expressions. */
/* Data about a single source file. */
-struct GTY(()) dwarf_file_data {
+struct GTY((for_user)) dwarf_file_data {
const char * filename;
int emitted_number;
};
ate_kind_label
};
-typedef struct GTY(()) addr_table_entry_struct {
+typedef struct GTY((for_user)) addr_table_entry_struct {
enum ate_kind kind;
unsigned int refcount;
unsigned int index;
/* And now, the support for symbolic debugging information. */
/* .debug_str support. */
-static int output_indirect_string (void **, void *);
static void dwarf2out_init (const char *);
static void dwarf2out_finish (const char *);
The children of each node form a circular list linked by
die_sib. die_child points to the node *before* the "first" child node. */
-typedef struct GTY((chain_circular ("%h.die_sib"))) die_struct {
+typedef struct GTY((chain_circular ("%h.die_sib"), for_user)) die_struct {
union die_symbol_or_type_node
{
const char * GTY ((tag ("0"))) die_symbol;
DW_AT_{,MIPS_}linkage_name once their DECL_ASSEMBLER_NAMEs are set. */
static GTY(()) limbo_die_node *deferred_asm_name;
+struct dwarf_file_hasher : ggc_hasher<dwarf_file_data *>
+{
+ typedef const char *compare_type;
+
+ static hashval_t hash (dwarf_file_data *);
+ static bool equal (dwarf_file_data *, const char *);
+};
+
/* Filenames referenced by this compilation unit. */
-static GTY((param_is (struct dwarf_file_data))) htab_t file_table;
+static GTY(()) hash_table<dwarf_file_hasher> *file_table;
+struct decl_die_hasher : ggc_hasher<die_node *>
+{
+ typedef tree compare_type;
+
+ static hashval_t hash (die_node *);
+ static bool equal (die_node *, tree);
+};
/* A hash table of references to DIE's that describe declarations.
The key is a DECL_UID() which is a unique number identifying each decl. */
-static GTY ((param_is (struct die_struct))) htab_t decl_die_table;
+static GTY (()) hash_table<decl_die_hasher> *decl_die_table;
+
+struct block_die_hasher : ggc_hasher<die_struct *>
+{
+ static hashval_t hash (die_struct *);
+ static bool equal (die_struct *, die_struct *);
+};
/* A hash table of references to DIE's that describe COMMON blocks.
The key is DECL_UID() ^ die_parent. */
-static GTY ((param_is (struct die_struct))) htab_t common_block_die_table;
+static GTY (()) hash_table<block_die_hasher> *common_block_die_table;
typedef struct GTY(()) die_arg_entry_struct {
dw_die_ref die;
};
/* Variable location list. */
-struct GTY (()) var_loc_list_def {
+struct GTY ((for_user)) var_loc_list_def {
struct var_loc_node * GTY (()) first;
/* Pointer to the last but one or last element of the
};
+struct decl_loc_hasher : ggc_hasher<var_loc_list *>
+{
+ typedef const_tree compare_type;
+
+ static hashval_t hash (var_loc_list *);
+ static bool equal (var_loc_list *, const_tree);
+};
+
/* Table of decl location linked lists. */
-static GTY ((param_is (var_loc_list))) htab_t decl_loc_table;
+static GTY (()) hash_table<decl_loc_hasher> *decl_loc_table;
/* Head and tail of call_arg_loc chain. */
static GTY (()) struct call_arg_loc_node *call_arg_locations;
static vec<dw_die_ref> block_map;
/* A cached location list. */
-struct GTY (()) cached_dw_loc_list_def {
+struct GTY ((for_user)) cached_dw_loc_list_def {
/* The DECL_UID of the decl that this entry describes. */
unsigned int decl_id;
};
typedef struct cached_dw_loc_list_def cached_dw_loc_list;
+struct dw_loc_list_hasher : ggc_hasher<cached_dw_loc_list *>
+{
+
+ typedef const_tree compare_type;
+
+ static hashval_t hash (cached_dw_loc_list *);
+ static bool equal (cached_dw_loc_list *, const_tree);
+};
+
/* Table of cached location lists. */
-static GTY ((param_is (cached_dw_loc_list))) htab_t cached_dw_loc_list_table;
+static GTY (()) hash_table<dw_loc_list_hasher> *cached_dw_loc_list_table;
/* A pointer to the base of a list of references to DIE's that
are uniquely identified by their tag, presence/absence of
static inline void add_AT_vec (dw_die_ref, enum dwarf_attribute, unsigned int,
unsigned int, unsigned char *);
static void add_AT_data8 (dw_die_ref, enum dwarf_attribute, unsigned char *);
-static hashval_t debug_str_do_hash (const void *);
-static int debug_str_eq (const void *, const void *);
static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *);
static inline const char *AT_string (dw_attr_ref);
static enum dwarf_form AT_string_form (dw_attr_ref);
static dw_die_ref strip_naming_typedef (tree, dw_die_ref);
static dw_die_ref lookup_type_die_strip_naming_typedef (tree);
static void equate_type_number_to_die (tree, dw_die_ref);
-static hashval_t decl_die_table_hash (const void *);
-static int decl_die_table_eq (const void *, const void *);
static dw_die_ref lookup_decl_die (tree);
-static hashval_t common_block_die_table_hash (const void *);
-static int common_block_die_table_eq (const void *, const void *);
-static hashval_t decl_loc_table_hash (const void *);
-static int decl_loc_table_eq (const void *, const void *);
static var_loc_list *lookup_decl_loc (const_tree);
static void equate_decl_number_to_die (tree, dw_die_ref);
static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *);
/* Hash and equality functions for debug_str_hash. */
-static hashval_t
-debug_str_do_hash (const void *x)
+hashval_t
+indirect_string_hasher::hash (indirect_string_node *x)
{
- return htab_hash_string (((const struct indirect_string_node *)x)->str);
+ return htab_hash_string (x->str);
}
-static int
-debug_str_eq (const void *x1, const void *x2)
+bool
+indirect_string_hasher::equal (indirect_string_node *x1, const char *x2)
{
- return strcmp ((((const struct indirect_string_node *)x1)->str),
- (const char *)x2) == 0;
+ return strcmp (x1->str, x2) == 0;
}
/* Add STR to the given string hash table. */
static struct indirect_string_node *
-find_AT_string_in_table (const char *str, htab_t table)
+find_AT_string_in_table (const char *str,
+ hash_table<indirect_string_hasher> *table)
{
struct indirect_string_node *node;
- void **slot;
- slot = htab_find_slot_with_hash (table, str,
- htab_hash_string (str), INSERT);
+ indirect_string_node **slot
+ = table->find_slot_with_hash (str, htab_hash_string (str), INSERT);
if (*slot == NULL)
{
node = ggc_cleared_alloc<indirect_string_node> ();
*slot = node;
}
else
- node = (struct indirect_string_node *) *slot;
+ node = *slot;
node->refcount++;
return node;
find_AT_string (const char *str)
{
if (! debug_str_hash)
- debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
- debug_str_eq, NULL);
+ debug_str_hash = hash_table<indirect_string_hasher>::create_ggc (10);
return find_AT_string_in_table (str, debug_str_hash);
}
return &a->dw_attr_val.v.val_loc_list;
}
+struct addr_hasher : ggc_hasher<addr_table_entry *>
+{
+ static hashval_t hash (addr_table_entry *);
+ static bool equal (addr_table_entry *, addr_table_entry *);
+};
+
/* Table of entries into the .debug_addr section. */
-static GTY ((param_is (addr_table_entry))) htab_t addr_index_table;
+static GTY (()) hash_table<addr_hasher> *addr_index_table;
/* Hash an address_table_entry. */
-static hashval_t
-addr_table_entry_do_hash (const void *x)
+hashval_t
+addr_hasher::hash (addr_table_entry *a)
{
- const addr_table_entry *a = (const addr_table_entry *) x;
inchash::hash hstate;
switch (a->kind)
{
/* Determine equality for two address_table_entries. */
-static int
-addr_table_entry_eq (const void *x1, const void *x2)
+bool
+addr_hasher::equal (addr_table_entry *a1, addr_table_entry *a2)
{
- const addr_table_entry *a1 = (const addr_table_entry *) x1;
- const addr_table_entry *a2 = (const addr_table_entry *) x2;
-
if (a1->kind != a2->kind)
return 0;
switch (a1->kind)
{
addr_table_entry *node;
addr_table_entry finder;
- void **slot;
gcc_assert (dwarf_split_debug_info);
if (! addr_index_table)
- addr_index_table = htab_create_ggc (10, addr_table_entry_do_hash,
- addr_table_entry_eq, NULL);
+ addr_index_table = hash_table<addr_hasher>::create_ggc (10);
init_addr_table_entry (&finder, kind, addr);
- slot = htab_find_slot (addr_index_table, &finder, INSERT);
+ addr_table_entry **slot = addr_index_table->find_slot (&finder, INSERT);
if (*slot == HTAB_EMPTY_ENTRY)
{
*slot = node;
}
else
- node = (addr_table_entry *) *slot;
+ node = *slot;
node->refcount++;
return node;
because the indexing code relies on htab_traverse to traverse nodes
in the same order for each run. */
-static int
-index_addr_table_entry (void **h, void *v)
+int
+index_addr_table_entry (addr_table_entry **h, unsigned int *index)
{
- addr_table_entry *node = (addr_table_entry *) *h;
- unsigned int *index = (unsigned int *) v;
+ addr_table_entry *node = *h;
/* Don't index unreferenced nodes. */
if (node->refcount == 0)
/* Returns a hash value for X (which really is a die_struct). */
-static hashval_t
-decl_die_table_hash (const void *x)
+inline hashval_t
+decl_die_hasher::hash (die_node *x)
{
- return (hashval_t) ((const_dw_die_ref) x)->decl_id;
+ return (hashval_t) x->decl_id;
}
/* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */
-static int
-decl_die_table_eq (const void *x, const void *y)
+inline bool
+decl_die_hasher::equal (die_node *x, tree y)
{
- return (((const_dw_die_ref) x)->decl_id == DECL_UID ((const_tree) y));
+ return (x->decl_id == DECL_UID (y));
}
/* Return the DIE associated with a given declaration. */
static inline dw_die_ref
lookup_decl_die (tree decl)
{
- return (dw_die_ref) htab_find_with_hash (decl_die_table, decl, DECL_UID (decl));
+ return decl_die_table->find_with_hash (decl, DECL_UID (decl));
}
/* Returns a hash value for X (which really is a var_loc_list). */
-static hashval_t
-decl_loc_table_hash (const void *x)
+inline hashval_t
+decl_loc_hasher::hash (var_loc_list *x)
{
- return (hashval_t) ((const var_loc_list *) x)->decl_id;
+ return (hashval_t) x->decl_id;
}
/* Return nonzero if decl_id of var_loc_list X is the same as
UID of decl *Y. */
-static int
-decl_loc_table_eq (const void *x, const void *y)
+inline bool
+decl_loc_hasher::equal (var_loc_list *x, const_tree y)
{
- return (((const var_loc_list *) x)->decl_id == DECL_UID ((const_tree) y));
+ return (x->decl_id == DECL_UID (y));
}
/* Return the var_loc list associated with a given declaration. */
{
if (!decl_loc_table)
return NULL;
- return (var_loc_list *)
- htab_find_with_hash (decl_loc_table, decl, DECL_UID (decl));
+ return decl_loc_table->find_with_hash (decl, DECL_UID (decl));
}
/* Returns a hash value for X (which really is a cached_dw_loc_list_list). */
-static hashval_t
-cached_dw_loc_list_table_hash (const void *x)
+inline hashval_t
+dw_loc_list_hasher::hash (cached_dw_loc_list *x)
{
- return (hashval_t) ((const cached_dw_loc_list *) x)->decl_id;
+ return (hashval_t) x->decl_id;
}
/* Return nonzero if decl_id of cached_dw_loc_list X is the same as
UID of decl *Y. */
-static int
-cached_dw_loc_list_table_eq (const void *x, const void *y)
+inline bool
+dw_loc_list_hasher::equal (cached_dw_loc_list *x, const_tree y)
{
- return (((const cached_dw_loc_list *) x)->decl_id
- == DECL_UID ((const_tree) y));
+ return (x->decl_id == DECL_UID (y));
}
/* Equate a DIE to a particular declaration. */
equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
{
unsigned int decl_id = DECL_UID (decl);
- void **slot;
- slot = htab_find_slot_with_hash (decl_die_table, decl, decl_id, INSERT);
- *slot = decl_die;
+ *decl_die_table->find_slot_with_hash (decl, decl_id, INSERT) = decl_die;
decl_die->decl_id = decl_id;
}
{
unsigned int decl_id;
var_loc_list *temp;
- void **slot;
struct var_loc_node *loc = NULL;
HOST_WIDE_INT bitsize = -1, bitpos = -1;
}
decl_id = DECL_UID (decl);
- slot = htab_find_slot_with_hash (decl_loc_table, decl, decl_id, INSERT);
+ var_loc_list **slot
+ = decl_loc_table->find_slot_with_hash (decl, decl_id, INSERT);
if (*slot == NULL)
{
temp = ggc_cleared_alloc<var_loc_list> ();
*slot = temp;
}
else
- temp = (var_loc_list *) *slot;
+ temp = *slot;
/* For PARM_DECLs try to keep around the original incoming value,
even if that means we'll emit a zero-range .debug_loc entry. */
struct indirect_string_node *node;
if (! skeleton_debug_str_hash)
- skeleton_debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
- debug_str_eq, NULL);
+ skeleton_debug_str_hash
+ = hash_table<indirect_string_hasher>::create_ggc (10);
node = find_AT_string_in_table (str, skeleton_debug_str_hash);
find_string_form (node);
/* Traversal function for the hash table. */
-static int
-file_name_acquire (void ** slot, void *data)
+int
+file_name_acquire (dwarf_file_data **slot, file_name_acquire_data *fnad)
{
- struct file_name_acquire_data *fnad = (struct file_name_acquire_data *) data;
- struct dwarf_file_data *d = (struct dwarf_file_data *) *slot;
+ struct dwarf_file_data *d = *slot;
struct file_info *fi;
const char *f;
fnad.files = files;
fnad.used_files = 0;
fnad.max_files = numfiles;
- htab_traverse (file_table, file_name_acquire, &fnad);
+ file_table->traverse<file_name_acquire_data *, file_name_acquire> (&fnad);
gcc_assert (fnad.used_files == fnad.max_files);
qsort (files, numfiles, sizeof (files[0]), file_info_cmp);
dw_loc_list_ref list;
var_loc_list *loc_list;
cached_dw_loc_list *cache;
- void **slot;
if (TREE_CODE (decl) == ERROR_MARK)
return false;
cache_p = false;
if (cache_p)
{
- cache = (cached_dw_loc_list *)
- htab_find_with_hash (cached_dw_loc_list_table, decl, DECL_UID (decl));
+ cache = cached_dw_loc_list_table->find_with_hash (decl, DECL_UID (decl));
if (cache)
list = cache->loc_list;
}
BLOCK_NONLOCALIZED_VARS and if the list has at least two elements. */
if (cache_p && list && list->dw_loc_next)
{
- slot = htab_find_slot_with_hash (cached_dw_loc_list_table, decl,
- DECL_UID (decl), INSERT);
+ cached_dw_loc_list **slot
+ = cached_dw_loc_list_table->find_slot_with_hash (decl,
+ DECL_UID (decl),
+ INSERT);
cache = ggc_cleared_alloc<cached_dw_loc_list> ();
cache->decl_id = DECL_UID (decl);
cache->loc_list = list;
tree save_fn;
tree context;
int was_abstract;
- htab_t old_decl_loc_table;
- htab_t old_cached_dw_loc_list_table;
+ hash_table<decl_loc_hasher> *old_decl_loc_table;
+ hash_table<dw_loc_list_hasher> *old_cached_dw_loc_list_table;
int old_call_site_count, old_tail_call_site_count;
struct call_arg_loc_node *old_call_arg_locations;
marked as unused by prune_unused_types. The DIE of the type is marked
only if the global variable using the type will actually be emitted. */
-static int
-premark_types_used_by_global_vars_helper (void **slot,
- void *data ATTRIBUTE_UNUSED)
+int
+premark_types_used_by_global_vars_helper (types_used_by_vars_entry **slot,
+ void *)
{
struct types_used_by_vars_entry *entry;
dw_die_ref die;
premark_types_used_by_global_vars (void)
{
if (types_used_by_vars_hash)
- htab_traverse (types_used_by_vars_hash,
- premark_types_used_by_global_vars_helper, NULL);
+ types_used_by_vars_hash
+ ->traverse<void *, premark_types_used_by_global_vars_helper> (NULL);
}
/* Generate a DW_TAG_GNU_call_site DIE in function DECL under SUBR_DIE
/* Returns a hash value for X (which really is a die_struct). */
-static hashval_t
-common_block_die_table_hash (const void *x)
+hashval_t
+block_die_hasher::hash (die_struct *d)
{
- const_dw_die_ref d = (const_dw_die_ref) x;
return (hashval_t) d->decl_id ^ htab_hash_pointer (d->die_parent);
}
/* Return nonzero if decl_id and die_parent of die_struct X is the same
as decl_id and die_parent of die_struct Y. */
-static int
-common_block_die_table_eq (const void *x, const void *y)
+bool
+block_die_hasher::equal (die_struct *x, die_struct *y)
{
- const_dw_die_ref d = (const_dw_die_ref) x;
- const_dw_die_ref e = (const_dw_die_ref) y;
- return d->decl_id == e->decl_id && d->die_parent == e->die_parent;
+ return x->decl_id == y->decl_id && x->die_parent == y->die_parent;
}
/* Generate a DIE to represent a declared data object.
}
if (common_block_die_table == NULL)
- common_block_die_table
- = htab_create_ggc (10, common_block_die_table_hash,
- common_block_die_table_eq, NULL);
+ common_block_die_table = hash_table<block_die_hasher>::create_ggc (10);
com_die_arg.decl_id = DECL_UID (com_decl);
com_die_arg.die_parent = context_die;
- com_die = (dw_die_ref) htab_find (common_block_die_table, &com_die_arg);
+ com_die = common_block_die_table->find (&com_die_arg);
loc = loc_list_from_tree (com_decl, 2);
if (com_die == NULL)
{
const char *cnam
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
- void **slot;
+ die_node **slot;
com_die = new_die (DW_TAG_common_block, context_die, decl);
add_name_and_src_coords_attributes (com_die, com_decl);
if (want_pubnames ())
add_pubname_string (cnam, com_die); /* ??? needed? */
com_die->decl_id = DECL_UID (com_decl);
- slot = htab_find_slot (common_block_die_table, com_die, INSERT);
- *slot = (void *) com_die;
+ slot = common_block_die_table->find_slot (com_die, INSERT);
+ *slot = com_die;
}
else if (get_AT (com_die, DW_AT_location) == NULL && loc)
{
call_site_count = -1;
tail_call_site_count = -1;
block_map.release ();
- htab_empty (decl_loc_table);
- htab_empty (cached_dw_loc_list_table);
+ decl_loc_table->empty ();
+ cached_dw_loc_list_table->empty ();
}
/* Output a marker (i.e. a label) for the beginning of the generated code for
/* Hash table routines for file_hash. */
-static int
-file_table_eq (const void *p1_p, const void *p2_p)
+bool
+dwarf_file_hasher::equal (dwarf_file_data *p1, const char *p2)
{
- const struct dwarf_file_data *const p1 =
- (const struct dwarf_file_data *) p1_p;
- const char *const p2 = (const char *) p2_p;
return filename_cmp (p1->filename, p2) == 0;
}
-static hashval_t
-file_table_hash (const void *p_p)
+hashval_t
+dwarf_file_hasher::hash (dwarf_file_data *p)
{
- const struct dwarf_file_data *const p = (const struct dwarf_file_data *) p_p;
return htab_hash_string (p->filename);
}
static struct dwarf_file_data *
lookup_filename (const char *file_name)
{
- void ** slot;
struct dwarf_file_data * created;
/* Check to see if the file name that was searched on the previous
return file_table_last_lookup;
/* Didn't match the previous lookup, search the table. */
- slot = htab_find_slot_with_hash (file_table, file_name,
- htab_hash_string (file_name), INSERT);
+ dwarf_file_data **slot
+ = file_table->find_slot_with_hash (file_name, htab_hash_string (file_name),
+ INSERT);
if (*slot)
- return (struct dwarf_file_data *) *slot;
+ return *slot;
created = ggc_alloc<dwarf_file_data> ();
created->filename = file_name;
/* Note in one location list that text section has changed. */
-static int
-var_location_switch_text_section_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+var_location_switch_text_section_1 (var_loc_list **slot, void *)
{
- var_loc_list *list = (var_loc_list *) *slot;
+ var_loc_list *list = *slot;
if (list->first)
list->last_before_switch
= list->last->next ? list->last->next : list->last;
if (decl_loc_table == NULL)
return;
- htab_traverse (decl_loc_table, var_location_switch_text_section_1, NULL);
+ decl_loc_table->traverse<void *, var_location_switch_text_section_1> (NULL);
}
/* Create a new line number table. */
Set have_multiple_function_sections to true in that case and
terminate htab traversal. */
-static int
-find_empty_loc_ranges_at_text_label (void **slot, void *)
+int
+find_empty_loc_ranges_at_text_label (var_loc_list **slot, int)
{
- var_loc_list *entry;
+ var_loc_list *entry = *slot;
struct var_loc_node *node;
- entry = (var_loc_list *) *slot;
node = entry->first;
if (node && node->next && node->next->label)
{
&& !have_multiple_function_sections
&& first_loclabel_num_not_at_text_label
&& decl_loc_table)
- htab_traverse (decl_loc_table, find_empty_loc_ranges_at_text_label,
- NULL);
+ decl_loc_table->traverse<int, find_empty_loc_ranges_at_text_label> (0);
in_first_function_p = false;
maybe_at_text_label_p = false;
}
dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
{
/* Allocate the file_table. */
- file_table = htab_create_ggc (50, file_table_hash,
- file_table_eq, NULL);
+ file_table = hash_table<dwarf_file_hasher>::create_ggc (50);
/* Allocate the decl_die_table. */
- decl_die_table = htab_create_ggc (10, decl_die_table_hash,
- decl_die_table_eq, NULL);
+ decl_die_table = hash_table<decl_die_hasher>::create_ggc (10);
/* Allocate the decl_loc_table. */
- decl_loc_table = htab_create_ggc (10, decl_loc_table_hash,
- decl_loc_table_eq, NULL);
+ decl_loc_table = hash_table<decl_loc_hasher>::create_ggc (10);
/* Allocate the cached_dw_loc_list_table. */
- cached_dw_loc_list_table
- = htab_create_ggc (10, cached_dw_loc_list_table_hash,
- cached_dw_loc_list_table_eq, NULL);
+ cached_dw_loc_list_table = hash_table<dw_loc_list_hasher>::create_ggc (10);
/* Allocate the initial hunk of the decl_scope_table. */
vec_alloc (decl_scope_table, 256);
because the indexing code relies on htab_traverse to traverse nodes
in the same order for each run. */
-static int
-index_string (void **h, void *v)
+int
+index_string (indirect_string_node **h, unsigned int *index)
{
- struct indirect_string_node *node = (struct indirect_string_node *) *h;
- unsigned int *index = (unsigned int *) v;
+ indirect_string_node *node = *h;
find_string_form (node);
if (node->form == DW_FORM_GNU_str_index && node->refcount > 0)
htab_traverse. Output the offset to a string and update the
current offset. */
-static int
-output_index_string_offset (void **h, void *v)
+int
+output_index_string_offset (indirect_string_node **h, unsigned int *offset)
{
- struct indirect_string_node *node = (struct indirect_string_node *) *h;
- unsigned int *offset = (unsigned int *) v;
+ indirect_string_node *node = *h;
if (node->form == DW_FORM_GNU_str_index && node->refcount > 0)
{
/* A helper function for dwarf2out_finish called through
htab_traverse. Output the indexed string. */
-static int
-output_index_string (void **h, void *v)
+int
+output_index_string (indirect_string_node **h, unsigned int *cur_idx)
{
- struct indirect_string_node *node = (struct indirect_string_node *) *h;
- unsigned int *cur_idx = (unsigned int *) v;
+ struct indirect_string_node *node = *h;
if (node->form == DW_FORM_GNU_str_index && node->refcount > 0)
{
/* A helper function for dwarf2out_finish called through
htab_traverse. Emit one queued .debug_str string. */
-static int
-output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED)
+int
+output_indirect_string (indirect_string_node **h, void *)
{
- struct indirect_string_node *node = (struct indirect_string_node *) *h;
+ struct indirect_string_node *node = *h;
node->form = find_string_form (node);
if (node->form == DW_FORM_strp && node->refcount > 0)
{
switch_to_section (debug_str_section);
if (!dwarf_split_debug_info)
- htab_traverse (debug_str_hash, output_indirect_string, NULL);
+ debug_str_hash->traverse<void *, output_indirect_string> (NULL);
else
{
unsigned int offset = 0;
unsigned int cur_idx = 0;
- htab_traverse (skeleton_debug_str_hash, output_indirect_string, NULL);
+ skeleton_debug_str_hash->traverse<void *, output_indirect_string> (NULL);
switch_to_section (debug_str_offsets_section);
- htab_traverse_noresize (debug_str_hash,
- output_index_string_offset,
- &offset);
+ debug_str_hash->traverse_noresize
+ <unsigned int *, output_index_string_offset> (&offset);
switch_to_section (debug_str_dwo_section);
- htab_traverse_noresize (debug_str_hash,
- output_index_string,
- &cur_idx);
+ debug_str_hash->traverse_noresize<unsigned int *, output_index_string>
+ (&cur_idx);
}
}
/* Callback for htab_traverse to assign an index to an entry in the
table, and to write that entry to the .debug_addr section. */
-static int
-output_addr_table_entry (void **slot, void *data)
+int
+output_addr_table_entry (addr_table_entry **slot, unsigned int *cur_index)
{
- addr_table_entry *entry = (addr_table_entry *) *slot;
- unsigned int *cur_index = (unsigned int *)data;
+ addr_table_entry *entry = *slot;
if (entry->refcount == 0)
{
output_addr_table (void)
{
unsigned int index = 0;
- if (addr_index_table == NULL || htab_size (addr_index_table) == 0)
+ if (addr_index_table == NULL || addr_index_table->size () == 0)
return;
switch_to_section (debug_addr_section);
- htab_traverse_noresize (addr_index_table, output_addr_table_entry, &index);
+ addr_index_table
+ ->traverse_noresize<unsigned int *, output_addr_table_entry> (&index);
}
#if ENABLE_ASSERT_CHECKING
if (s->refcount
== ((DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) ? 1 : 2))
{
- void ** slot;
- slot = htab_find_slot_with_hash (debug_str_hash, s->str,
- htab_hash_string (s->str),
- INSERT);
+ indirect_string_node **slot
+ = debug_str_hash->find_slot_with_hash (s->str,
+ htab_hash_string (s->str),
+ INSERT);
gcc_assert (*slot == NULL);
*slot = s;
}
prune_unused_types_mark (base_type, 1);
if (debug_str_hash)
- htab_empty (debug_str_hash);
+ debug_str_hash->empty ();
if (skeleton_debug_str_hash)
- htab_empty (skeleton_debug_str_hash);
+ skeleton_debug_str_hash->empty ();
prune_unused_types_prune (comp_unit_die ());
for (node = limbo_die_list; node; node = node->next)
prune_unused_types_prune (node->die);
/* Set the parameter to true if there are any relative pathnames in
the file table. */
-static int
-file_table_relative_p (void ** slot, void *param)
+int
+file_table_relative_p (dwarf_file_data **slot, bool *p)
{
- bool *p = (bool *) param;
- struct dwarf_file_data *d = (struct dwarf_file_data *) *slot;
+ struct dwarf_file_data *d = *slot;
if (!IS_ABSOLUTE_PATH (d->filename))
{
*p = true;
else if (get_AT (comp_unit_die (), DW_AT_comp_dir) == NULL)
{
bool p = false;
- htab_traverse (file_table, file_table_relative_p, &p);
+ file_table->traverse<bool *, file_table_relative_p> (&p);
if (p)
add_comp_dir_attribute (comp_unit_die ());
}
if (addr_index_table != NULL)
{
unsigned int index = 0;
- htab_traverse_noresize (addr_index_table,
- index_addr_table_entry, &index);
+ addr_index_table
+ ->traverse_noresize<unsigned int *, index_addr_table_entry>
+ (&index);
}
}
skeleton die attrs are added when the skeleton type unit is
created, so ensure it is created by this point. */
add_top_level_skeleton_die_attrs (main_comp_unit_die);
- htab_traverse_noresize (debug_str_hash, index_string, &index);
+ debug_str_hash->traverse_noresize<unsigned int *, index_string> (&index);
}
/* Output all of the compilation units. We put the main one last so that
+2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
+
+ * trans-decl.c, trans.c, trans.h: Use hash_table instead of hashtab.
+
2014-10-11 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/48979
gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL_TREE);
}
-static GTY ((param_is (struct module_htab_entry))) htab_t module_htab;
-
-/* Hash and equality functions for module_htab. */
-
-static hashval_t
-module_htab_do_hash (const void *x)
+struct module_hasher : ggc_hasher<module_htab_entry *>
{
- return htab_hash_string (((const struct module_htab_entry *)x)->name);
-}
+ typedef const char *compare_type;
-static int
-module_htab_eq (const void *x1, const void *x2)
-{
- return strcmp ((((const struct module_htab_entry *)x1)->name),
- (const char *)x2) == 0;
-}
+ static hashval_t hash (module_htab_entry *s) { return htab_hash_string (s); }
+ static bool
+ equal (module_htab_entry *a, const char *b)
+ {
+ return !strcmp (a->name, b);
+ }
+};
+
+static GTY (()) hash_table<module_hasher> *module_htab;
/* Hash and equality functions for module_htab's decls. */
-static hashval_t
-module_htab_decls_hash (const void *x)
+hashval_t
+module_decl_hasher::hash (tree t)
{
- const_tree t = (const_tree) x;
const_tree n = DECL_NAME (t);
if (n == NULL_TREE)
n = TYPE_NAME (TREE_TYPE (t));
return htab_hash_string (IDENTIFIER_POINTER (n));
}
-static int
-module_htab_decls_eq (const void *x1, const void *x2)
+bool
+module_decl_hasher::equal (tree t1, const char *x2)
{
- const_tree t1 = (const_tree) x1;
const_tree n1 = DECL_NAME (t1);
if (n1 == NULL_TREE)
n1 = TYPE_NAME (TREE_TYPE (t1));
- return strcmp (IDENTIFIER_POINTER (n1), (const char *) x2) == 0;
+ return strcmp (IDENTIFIER_POINTER (n1), x2) == 0;
}
struct module_htab_entry *
gfc_find_module (const char *name)
{
- void **slot;
-
if (! module_htab)
- module_htab = htab_create_ggc (10, module_htab_do_hash,
- module_htab_eq, NULL);
+ module_htab = hash_table<module_hasher>::create_ggc (10);
- slot = htab_find_slot_with_hash (module_htab, name,
- htab_hash_string (name), INSERT);
+ module_htab_entry **slot
+ = module_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT);
if (*slot == NULL)
{
module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
entry->name = gfc_get_string (name);
- entry->decls = htab_create_ggc (10, module_htab_decls_hash,
- module_htab_decls_eq, NULL);
- *slot = (void *) entry;
+ entry->decls = hash_table<module_decl_hasher>::create_ggc (10);
+ *slot = entry;
}
- return (struct module_htab_entry *) *slot;
+ return *slot;
}
void
gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
{
- void **slot;
const char *name;
if (DECL_NAME (decl))
gcc_assert (TREE_CODE (decl) == TYPE_DECL);
name = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl)));
}
- slot = htab_find_slot_with_hash (entry->decls, name,
- htab_hash_string (name), INSERT);
+ tree *slot
+ = entry->decls->find_slot_with_hash (name, htab_hash_string (name),
+ INSERT);
if (*slot == NULL)
- *slot = (void *) decl;
+ *slot = decl;
}
static struct module_htab_entry *cur_module;
for (rent = use_stmt->rename; rent; rent = rent->next)
{
tree decl, local_name;
- void **slot;
if (rent->op != INTRINSIC_NONE)
continue;
- slot = htab_find_slot_with_hash (entry->decls, rent->use_name,
- htab_hash_string (rent->use_name),
- INSERT);
+ hashval_t hash = htab_hash_string (rent->use_name);
+ tree *slot = entry->decls->find_slot_with_hash (rent->use_name, hash,
+ INSERT);
if (*slot == NULL)
{
gfc_symtree *st;
else
{
*slot = error_mark_node;
- htab_clear_slot (entry->decls, slot);
+ entry->decls->clear_slot (slot);
continue;
}
*slot = decl;
entry = gfc_find_module (ns->proc_name->name);
if (entry->namespace_decl)
/* Buggy sourcecode, using a module before defining it? */
- htab_empty (entry->decls);
+ entry->decls->empty ();
entry->namespace_decl = ns->proc_name->backend_decl;
gfc_generate_module_vars (ns);
/* Get the appropriate return statement for a procedure. */
tree gfc_generate_return (void);
-struct GTY(()) module_htab_entry {
+struct module_decl_hasher : ggc_hasher<tree_node *>
+{
+ typedef const char *compare_type;
+
+ static hashval_t hash (tree);
+ static bool equal (tree, const char *);
+};
+
+struct GTY((for_user)) module_htab_entry {
const char *name;
tree namespace_decl;
- htab_t GTY ((param_is (union tree_node))) decls;
+ hash_table<module_decl_hasher> *GTY (()) decls;
};
struct module_htab_entry *gfc_find_module (const char *);
htab_t epilogue_insn_hash;
\f
-htab_t types_used_by_vars_hash = NULL;
+hash_table<used_type_hasher> *types_used_by_vars_hash = NULL;
vec<tree, va_gc> *types_used_by_cur_var_decl;
/* Forward declarations. */
HOST_WIDE_INT full_size;
};
-/* A table of addresses that represent a stack slot. The table is a mapping
- from address RTXen to a temp slot. */
-static GTY((param_is(struct temp_slot_address_entry))) htab_t temp_slot_address_table;
-static size_t n_temp_slots_in_use;
-
-/* Entry for the above hash table. */
-struct GTY(()) temp_slot_address_entry {
+/* Entry for the below hash table. */
+struct GTY((for_user)) temp_slot_address_entry {
hashval_t hash;
rtx address;
struct temp_slot *temp_slot;
};
+struct temp_address_hasher : ggc_hasher<temp_slot_address_entry *>
+{
+ static hashval_t hash (temp_slot_address_entry *);
+ static bool equal (temp_slot_address_entry *, temp_slot_address_entry *);
+};
+
+/* A table of addresses that represent a stack slot. The table is a mapping
+ from address RTXen to a temp slot. */
+static GTY(()) hash_table<temp_address_hasher> *temp_slot_address_table;
+static size_t n_temp_slots_in_use;
+
/* Removes temporary slot TEMP from LIST. */
static void
}
/* Return the hash value for an address -> temp slot mapping. */
-static hashval_t
-temp_slot_address_hash (const void *p)
+hashval_t
+temp_address_hasher::hash (temp_slot_address_entry *t)
{
- const struct temp_slot_address_entry *t;
- t = (const struct temp_slot_address_entry *) p;
return t->hash;
}
/* Compare two address -> temp slot mapping entries. */
-static int
-temp_slot_address_eq (const void *p1, const void *p2)
+bool
+temp_address_hasher::equal (temp_slot_address_entry *t1,
+ temp_slot_address_entry *t2)
{
- const struct temp_slot_address_entry *t1, *t2;
- t1 = (const struct temp_slot_address_entry *) p1;
- t2 = (const struct temp_slot_address_entry *) p2;
return exp_equiv_p (t1->address, t2->address, 0, true);
}
static void
insert_temp_slot_address (rtx address, struct temp_slot *temp_slot)
{
- void **slot;
struct temp_slot_address_entry *t = ggc_alloc<temp_slot_address_entry> ();
t->address = address;
t->temp_slot = temp_slot;
t->hash = temp_slot_address_compute_hash (t);
- slot = htab_find_slot_with_hash (temp_slot_address_table, t, t->hash, INSERT);
- *slot = t;
+ *temp_slot_address_table->find_slot_with_hash (t, t->hash, INSERT) = t;
}
/* Remove an address -> temp slot mapping entry if the temp slot is
not in use anymore. Callback for remove_unused_temp_slot_addresses. */
-static int
-remove_unused_temp_slot_addresses_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+remove_unused_temp_slot_addresses_1 (temp_slot_address_entry **slot, void *)
{
- const struct temp_slot_address_entry *t;
- t = (const struct temp_slot_address_entry *) *slot;
+ const struct temp_slot_address_entry *t = *slot;
if (! t->temp_slot->in_use)
- htab_clear_slot (temp_slot_address_table, slot);
+ temp_slot_address_table->clear_slot (slot);
return 1;
}
{
/* Use quicker clearing if there aren't any active temp slots. */
if (n_temp_slots_in_use)
- htab_traverse (temp_slot_address_table,
- remove_unused_temp_slot_addresses_1,
- NULL);
+ temp_slot_address_table->traverse
+ <void *, remove_unused_temp_slot_addresses_1> (NULL);
else
- htab_empty (temp_slot_address_table);
+ temp_slot_address_table->empty ();
}
/* Find the temp slot corresponding to the object at address X. */
tmp.address = x;
tmp.temp_slot = NULL;
tmp.hash = temp_slot_address_compute_hash (&tmp);
- t = (struct temp_slot_address_entry *)
- htab_find_with_hash (temp_slot_address_table, &tmp, tmp.hash);
+ t = temp_slot_address_table->find_with_hash (&tmp, tmp.hash);
if (t)
return t->temp_slot;
/* Set up the table to map addresses to temp slots. */
if (! temp_slot_address_table)
- temp_slot_address_table = htab_create_ggc (32,
- temp_slot_address_hash,
- temp_slot_address_eq,
- NULL);
+ temp_slot_address_table = hash_table<temp_address_hasher>::create_ggc (32);
else
- htab_empty (temp_slot_address_table);
+ temp_slot_address_table->empty ();
}
\f
/* Functions and data structures to keep track of the values hard regs
/* Hash function of the types_used_by_vars_entry hash table. */
hashval_t
-types_used_by_vars_do_hash (const void *x)
+used_type_hasher::hash (types_used_by_vars_entry *entry)
{
- const struct types_used_by_vars_entry *entry =
- (const struct types_used_by_vars_entry *) x;
-
return hash_types_used_by_vars_entry (entry);
}
/*Equality function of the types_used_by_vars_entry hash table. */
-int
-types_used_by_vars_eq (const void *x1, const void *x2)
+bool
+used_type_hasher::equal (types_used_by_vars_entry *e1,
+ types_used_by_vars_entry *e2)
{
- const struct types_used_by_vars_entry *e1 =
- (const struct types_used_by_vars_entry *) x1;
- const struct types_used_by_vars_entry *e2 =
- (const struct types_used_by_vars_entry *)x2;
-
return (e1->var_decl == e2->var_decl && e1->type == e2->type);
}
{
if (type != NULL && var_decl != NULL)
{
- void **slot;
+ types_used_by_vars_entry **slot;
struct types_used_by_vars_entry e;
e.var_decl = var_decl;
e.type = type;
if (types_used_by_vars_hash == NULL)
- types_used_by_vars_hash =
- htab_create_ggc (37, types_used_by_vars_do_hash,
- types_used_by_vars_eq, NULL);
- slot = htab_find_slot_with_hash (types_used_by_vars_hash, &e,
- hash_types_used_by_vars_entry (&e), INSERT);
+ types_used_by_vars_hash
+ = hash_table<used_type_hasher>::create_ggc (37);
+
+ slot = types_used_by_vars_hash->find_slot (&e, INSERT);
if (*slot == NULL)
{
struct types_used_by_vars_entry *entry;
/* Nonzero if at least one trampoline has been created. */
extern int trampolines_created;
-struct GTY(()) types_used_by_vars_entry {
+struct GTY((for_user)) types_used_by_vars_entry {
tree type;
tree var_decl;
};
+struct used_type_hasher : ggc_hasher<types_used_by_vars_entry *>
+{
+ static hashval_t hash (types_used_by_vars_entry *);
+ static bool equal (types_used_by_vars_entry *, types_used_by_vars_entry *);
+};
+
/* Hash table making the relationship between a global variable
and the types it references in its initializer. The key of the
entry is a referenced type, and the value is the DECL of the global
variable. types_use_by_vars_do_hash and types_used_by_vars_eq below are
the hash and equality functions to use for this hash table. */
-extern GTY((param_is (struct types_used_by_vars_entry))) htab_t
- types_used_by_vars_hash;
+extern GTY(()) hash_table<used_type_hasher> *types_used_by_vars_hash;
-hashval_t types_used_by_vars_do_hash (const void*);
-int types_used_by_vars_eq (const void *, const void *);
void types_used_by_var_decl_insert (tree type, tree var_decl);
/* During parsing of a global variable, this vector contains the types
if (is_ptr)
offset_to_star = star - type_id;
+ if (strstr (type_id, "char*"))
+ {
+ type_id = strtoken (0, ",>", &next);
+ continue;
+ }
+
char *field_name = xstrdup (type_id);
type_p arg_type;
;
else if (strcmp (oo->name, "variable_size") == 0)
;
+ else if (strcmp (oo->name, "for_user") == 0)
+ ;
else
error_at_line (d->line, "unknown option `%s'\n", oo->name);
oprintf (d->of, "}\n");
}
-
/* Emit the user-callable functions needed to mark all the types used
by the user structure S. PREFIX is the prefix to use to
distinguish ggc and pch markers. D contains data needed to pass to
memset (&d, 0, sizeof (d));
d.of = get_output_file_for_structure (s, param);
+
+ bool for_user = false;
for (opt = s->u.s.opt; opt; opt = opt->next)
if (strcmp (opt->name, "chain_next") == 0
&& opt->kind == OPTION_STRING)
else if (strcmp (opt->name, "mark_hook") == 0
&& opt->kind == OPTION_STRING)
mark_hook_name = opt->info.string;
+ else if (strcmp (opt->name, "for_user") == 0)
+ for_user = true;
if (chain_prev != NULL && chain_next == NULL)
error_at_line (&s->u.s.line, "chain_prev without chain_next");
if (chain_circular != NULL && chain_next != NULL)
if (orig_s->kind == TYPE_USER_STRUCT)
write_user_marking_functions (orig_s, wtd, &d);
+
+ if (for_user)
+ {
+ write_user_func_for_structure_body (orig_s, wtd->prefix, &d);
+ write_user_func_for_structure_ptr (d.of, orig_s, wtd);
+ }
}
/* Write user-callable entry points for the PCH walking routines. */
if (orig_s->kind == TYPE_USER_STRUCT)
write_pch_user_walking_functions (s, &d);
+
+ for (options_p o = s->u.s.opt; o; o = o->next)
+ if (strcmp (o->name, "for_user") == 0)
+ {
+ write_pch_user_walking_for_structure_body (s, &d);
+ break;
+ }
}
/* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
hence enlarge the param_structs list of types. */
set_gc_used (variables);
+ for (type_p t = structures; t; t = t->next)
+ {
+ bool for_user = false;
+ for (options_p o = t->u.s.opt; o; o = o->next)
+ if (strcmp (o->name, "for_user") == 0)
+ {
+ for_user = true;
+ break;
+ }
+
+ if (for_user)
+ set_gc_used_type (t, GC_POINTED_TO, NULL);
+ }
/* The state at this point is read from the state input file or by
parsing source files and optionally augmented by parsing plugin
source files. Write it now. */
{
}
+static inline void
+gt_pch_nx (unsigned int)
+{
+}
+
#endif
#define GCC_GIMPLE_SSA_H
#include "hash-map.h"
+#include "tree-hasher.h"
#include "tree-ssa-operands.h"
/* This structure is used to map a gimple statement to a label,
tree label_or_list;
};
+struct ssa_name_hasher : ggc_hasher<tree>
+{
+ /* Hash a tree in a uid_decl_map. */
+
+ static hashval_t
+ hash (tree item)
+ {
+ return item->ssa_name.var->decl_minimal.uid;
+ }
+
+ /* Return true if the DECL_UID in both trees are equal. */
+
+ static bool
+ equal (tree a, tree b)
+{
+ return (a->ssa_name.var->decl_minimal.uid == b->ssa_name.var->decl_minimal.uid);
+}
+};
+
/* Gimple dataflow datastructure. All publicly available fields shall have
gimple_ accessor defined, all publicly modifiable fields should have
gimple_set accessor. */
means that the first reference to this variable in the function is a
USE or a VUSE. In those cases, the SSA renamer creates an SSA name
for this variable with an empty defining statement. */
- htab_t GTY((param_is (union tree_node))) default_defs;
+ hash_table<ssa_name_hasher> *default_defs;
/* True if there are any symbols that need to be renamed. */
unsigned int ssa_renaming_needed : 1;
{
}
+ static void
+ pch_nx_helper (unsigned int, gt_pointer_operator, void *)
+ {
+ }
+
+ static void
+ pch_nx_helper (bool, gt_pointer_operator, void *)
+ {
+ }
+
template<typename T>
static void
pch_nx_helper (T *&x, gt_pointer_operator op, void *cookie)
#include "ggc.h"
#include "hashtab.h"
+#include <new>
template<typename, typename, typename> class hash_map;
template<typename, typename> class hash_set;
return existing == candidate;
}
+/* Hasher for entry in gc memory. */
+
+template<typename T>
+struct ggc_hasher
+{
+ typedef T value_type;
+ typedef T compare_type;
+ typedef int store_values_directly;
+
+ static void remove (T) {}
+
+ static void
+ ggc_mx (T p)
+ {
+ extern void gt_ggc_mx (T &);
+ gt_ggc_mx (p);
+ }
+
+ static void
+ pch_nx (T &p)
+ {
+ extern void gt_pch_nx (T &);
+ gt_pch_nx (p);
+ }
+
+ static void
+ pch_nx (T &p, gt_pointer_operator op, void *cookie)
+ {
+ op (&p, cookie);
+ }
+};
+
/* Table of primes and their inversion information. */
explicit hash_table (size_t, bool ggc = false);
~hash_table ();
+ /* Create a hash_table in gc memory. */
+
+ static hash_table *
+ create_ggc (size_t n)
+ {
+ hash_table *table = ggc_alloc<hash_table> ();
+ new (table) hash_table (n, true);
+ return table;
+ }
+
/* Current size (in entries) of the hash table. */
size_t size () const { return m_size; }
private:
template<typename T> friend void gt_ggc_mx (hash_table<T> *);
template<typename T> friend void gt_pch_nx (hash_table<T> *);
- template<typename T> friend void hashtab_entry_note_pointers (void *, void *, gt_pointer_operator, void *);
- template<typename T, typename U, typename V> friend void gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *);
- template<typename T, typename U> friend void gt_pch_nx (hash_set<T, U> *, gt_pointer_operator, void *);
+ template<typename T> friend void
+ hashtab_entry_note_pointers (void *, void *, gt_pointer_operator, void *);
+ template<typename T, typename U, typename V> friend void
+ gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *);
+ template<typename T, typename U> friend void gt_pch_nx (hash_set<T, U> *,
+ gt_pointer_operator,
+ void *);
+ template<typename T> friend void gt_pch_nx (hash_table<T> *,
+ gt_pointer_operator, void *);
value_type *find_empty_slot_for_expand (hashval_t);
void expand ();
static void
gt_pch_nx (hash_table<D> *h)
{
- bool success ATTRIBUTE_UNUSED
+ bool success
= gt_pch_note_object (h->m_entries, h, hashtab_entry_note_pointers<D>);
gcc_checking_assert (success);
for (size_t i = 0; i < h->m_size; i++)
}
}
+template<typename D>
+static inline void
+gt_pch_nx (hash_table<D> *h, gt_pointer_operator op, void *cookie)
+{
+ op (&h->m_entries, cookie);
+}
+
#endif /* TYPED_HASHTAB_H */
+2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
+
+ * class.c, decl.c, except.c, expr.c, java-tree.h, lang.c: Use
+ hash_table instead of hashtab.
+
2014-10-07 Marek Polacek <polacek@redhat.com>
* jvgenmain.c (main): Provide declarations for JvRunMain{,Name}.
/* Initialize the initialized (static) class table. */
if (access_flags & ACC_STATIC)
DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl) =
- htab_create_ggc (50, htab_hash_pointer, htab_eq_pointer, NULL);
+ hash_table<ict_hasher>::create_ggc (50);
DECL_CHAIN (fndecl) = TYPE_METHODS (this_class);
TYPE_METHODS (this_class) = fndecl;
/* Add an entry to the type assertion table. Callback used during hashtable
traversal. */
-static int
-add_assertion_table_entry (void **htab_entry, void *ptr)
+int
+add_assertion_table_entry (type_assertion **slot, vec<constructor_elt, va_gc> **v)
{
tree entry;
tree code_val, op1_utf8, op2_utf8;
- vec<constructor_elt, va_gc> **v
- = ((vec<constructor_elt, va_gc> **) ptr);
- type_assertion *as = (type_assertion *) *htab_entry;
+ type_assertion *as = *slot;
code_val = build_int_cst (NULL_TREE, as->assertion_code);
emit_assertion_table (tree klass)
{
tree null_entry, ctor, table_decl;
- htab_t assertions_htab = TYPE_ASSERTIONS (klass);
+ hash_table<type_assertion_hasher> *assertions_htab = TYPE_ASSERTIONS (klass);
vec<constructor_elt, va_gc> *v = NULL;
/* Iterate through the hash table. */
- htab_traverse (assertions_htab, add_assertion_table_entry, &v);
+ assertions_htab
+ ->traverse<vec<constructor_elt, va_gc> **, add_assertion_table_entry> (&v);
/* Finish with a null entry. */
null_entry = build_assertion_table_entry (integer_zero_node,
gcc_obstack_init (&temporary_obstack);
}
\f
-static hashval_t java_treetreehash_hash (const void *);
-static int java_treetreehash_compare (const void *, const void *);
-
/* A hash table mapping trees to trees. Used generally. */
#define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t))
-static hashval_t
-java_treetreehash_hash (const void *k_p)
+hashval_t
+treetreehasher::hash (treetreehash_entry *k)
{
- const struct treetreehash_entry *const k
- = (const struct treetreehash_entry *) k_p;
return JAVA_TREEHASHHASH_H (k->key);
}
-static int
-java_treetreehash_compare (const void * k1_p, const void * k2_p)
+bool
+treetreehasher::equal (treetreehash_entry *k1, tree k2)
{
- const struct treetreehash_entry *const k1
- = (const struct treetreehash_entry *) k1_p;
- const_tree const k2 = (const_tree) k2_p;
return (k1->key == k2);
}
tree
-java_treetreehash_find (htab_t ht, tree t)
+java_treetreehash_find (hash_table<treetreehasher> *ht, tree t)
{
struct treetreehash_entry *e;
hashval_t hv = JAVA_TREEHASHHASH_H (t);
- e = (struct treetreehash_entry *) htab_find_with_hash (ht, t, hv);
+ e = ht->find_with_hash (t, hv);
if (e == NULL)
return NULL;
else
}
tree *
-java_treetreehash_new (htab_t ht, tree t)
+java_treetreehash_new (hash_table<treetreehasher> *ht, tree t)
{
- void **e;
struct treetreehash_entry *tthe;
hashval_t hv = JAVA_TREEHASHHASH_H (t);
- e = htab_find_slot_with_hash (ht, t, hv, INSERT);
+ treetreehash_entry **e = ht->find_slot_with_hash (t, hv, INSERT);
if (*e == NULL)
{
tthe = ggc_cleared_alloc<treetreehash_entry> ();
*e = tthe;
}
else
- tthe = (struct treetreehash_entry *) *e;
+ tthe = *e;
return &tthe->value;
}
-htab_t
+hash_table<treetreehasher> *
java_treetreehash_create (size_t size)
{
- return htab_create_ggc (size, java_treetreehash_hash,
- java_treetreehash_compare, NULL);
+ return hash_table<treetreehasher>::create_ggc (size);
}
/* Break down qualified IDENTIFIER into package and class-name components.
variable to the block_body */
fbody = DECL_SAVED_TREE (fndecl);
block_body = BIND_EXPR_BODY (fbody);
- htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
- attach_init_test_initialization_flags, block_body);
+ hash_table<treetreehasher> *ht = DECL_FUNCTION_INIT_TEST_TABLE (fndecl);
+ ht->traverse<tree, attach_init_test_initialization_flags> (block_body);
}
finish_method (fndecl);
return exp;
}
-static int
-expand_catch_class (void **entry, void *x ATTRIBUTE_UNUSED)
+int
+expand_catch_class (treetreehash_entry **entry, int)
{
- struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
+ struct treetreehash_entry *ite = *entry;
tree addr = TREE_VALUE ((tree)ite->value);
tree decl;
STRIP_NOPS (addr);
java_expand_catch_classes (tree this_class)
{
if (TYPE_TO_RUNTIME_MAP (this_class))
- htab_traverse
- (TYPE_TO_RUNTIME_MAP (this_class),
- expand_catch_class, NULL);
+ TYPE_TO_RUNTIME_MAP (this_class)->traverse<int, expand_catch_class> (0);
}
/* Build and push the variable that will hold the exception object
\f
/* Return true if two type assertions are equal. */
-static int
-type_assertion_eq (const void * k1_p, const void * k2_p)
+bool
+type_assertion_hasher::equal (type_assertion *k1, type_assertion *k2)
{
- const type_assertion k1 = *(const type_assertion *)k1_p;
- const type_assertion k2 = *(const type_assertion *)k2_p;
- return (k1.assertion_code == k2.assertion_code
- && k1.op1 == k2.op1
- && k1.op2 == k2.op2);
+ return (k1->assertion_code == k2->assertion_code
+ && k1->op1 == k2->op1
+ && k1->op2 == k2->op2);
}
/* Hash a type assertion. */
-static hashval_t
-type_assertion_hash (const void *p)
+hashval_t
+type_assertion_hasher::hash (type_assertion *k_p)
{
- const type_assertion *k_p = (const type_assertion *) p;
hashval_t hash = iterative_hash (&k_p->assertion_code, sizeof
k_p->assertion_code, 0);
void
add_type_assertion (tree klass, int assertion_code, tree op1, tree op2)
{
- htab_t assertions_htab;
+ hash_table<type_assertion_hasher> *assertions_htab;
type_assertion as;
- void **as_pp;
+ type_assertion **as_pp;
assertions_htab = TYPE_ASSERTIONS (klass);
if (assertions_htab == NULL)
{
- assertions_htab = htab_create_ggc (7, type_assertion_hash,
- type_assertion_eq, NULL);
+ assertions_htab = hash_table<type_assertion_hasher>::create_ggc (7);
TYPE_ASSERTIONS (current_class) = assertions_htab;
}
as.op1 = op1;
as.op2 = op2;
- as_pp = htab_find_slot (assertions_htab, &as, INSERT);
+ as_pp = assertions_htab->find_slot (&as, INSERT);
/* Don't add the same assertion twice. */
if (*as_pp)
return;
*as_pp = ggc_alloc<type_assertion> ();
- **(type_assertion **)as_pp = as;
+ **as_pp = as;
}
\f
/* Attach to PTR (a block) the declaration found in ENTRY. */
int
-attach_init_test_initialization_flags (void **entry, void *ptr)
+attach_init_test_initialization_flags (treetreehash_entry **slot, tree block)
{
- tree block = (tree)ptr;
- struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
+ treetreehash_entry *ite = *slot;
if (block != error_mark_node)
{
&& TREE_CODE (TREE_TYPE (NODE)) != POINTER_TYPE) \
|| TREE_CODE (NODE) == REAL_CST)
+struct GTY((for_user)) treetreehash_entry {
+ tree key;
+ tree value;
+};
+
+struct treetreehasher : ggc_hasher<treetreehash_entry *>
+{
+ typedef tree compare_type;
+
+ static hashval_t hash (treetreehash_entry *);
+ static bool equal (treetreehash_entry *, tree);
+};
+
+struct ict_hasher : ggc_hasher<tree_node *>
+{
+ static hashval_t hash (tree t) { return htab_hash_pointer (t); }
+ static bool equal (tree a, tree b) { return a == b; }
+};
+
/* DECL_LANG_SPECIFIC for FUNCTION_DECLs. */
struct GTY(()) lang_decl_func {
/* tree chain; not yet used. */
tree exc_obj; /* Decl holding the exception object. */
/* Class initialization test variables */
- htab_t GTY ((param_is (struct treetreehash_entry))) init_test_table;
+ hash_table<treetreehasher> *init_test_table;
/* Initialized (static) Class Table */
- htab_t GTY ((param_is (union tree_node))) ict;
+ hash_table<ict_hasher> *ict;
unsigned int native : 1; /* Nonzero if this is a native method */
unsigned int strictfp : 1;
unsigned int varargs : 1; /* Varargs method. */
};
-struct GTY(()) treetreehash_entry {
- tree key;
- tree value;
-};
-
/* These represent the possible assertion_codes that can be emitted in the
type assertion table. */
enum
JV_ANNOTATION_DEFAULT_KIND
} jv_attr_kind;
-typedef struct GTY(()) type_assertion {
+typedef struct GTY((for_user)) type_assertion {
int assertion_code; /* 'opcode' for the type of this assertion. */
tree op1; /* First operand. */
tree op2; /* Second operand. */
} type_assertion;
-extern tree java_treetreehash_find (htab_t, tree);
-extern tree * java_treetreehash_new (htab_t, tree);
-extern htab_t java_treetreehash_create (size_t size);
+struct type_assertion_hasher : ggc_hasher<type_assertion *>
+{
+ static hashval_t hash (type_assertion *);
+ static bool equal (type_assertion *, type_assertion *);
+};
+
+extern tree java_treetreehash_find (hash_table<treetreehasher> *, tree);
+extern tree * java_treetreehash_new (hash_table<treetreehasher> *, tree);
+extern hash_table<treetreehasher> *java_treetreehash_create (size_t size);
/* DECL_LANG_SPECIFIC for VAR_DECL, PARM_DECL and sometimes FIELD_DECL
(access methods on outer class fields) and final fields. */
type matcher. */
vec<constructor_elt, va_gc> *catch_classes;
- htab_t GTY ((param_is (struct treetreehash_entry))) type_to_runtime_map;
+ hash_table<treetreehasher> *type_to_runtime_map;
/* The mapping of classes to exception region
markers. */
- htab_t GTY ((param_is (struct type_assertion))) type_assertions;
+ hash_table<type_assertion_hasher> *type_assertions;
/* Table of type assertions to be evaluated
by the runtime when this class is loaded. */
extern tree build_known_method_ref (tree, tree, tree, tree, vec<tree, va_gc> *,
tree);
extern tree build_class_init (tree, tree);
-extern int attach_init_test_initialization_flags (void **, void *);
+extern int attach_init_test_initialization_flags (treetreehash_entry **, tree);
extern tree build_invokevirtual (tree, tree, tree);
extern tree build_invokeinterface (tree, tree);
extern tree build_jni_stub (tree);
static void put_decl_node (tree, int);
static void java_print_error_function (diagnostic_context *, const char *,
diagnostic_info *);
-static int merge_init_test_initialization (void * *, void *);
-static int inline_init_test_initialization (void * *, void *);
static bool java_dump_tree (void *, tree);
static void dump_compound_expr (dump_info_p, tree);
static bool java_decl_ok_for_sibcall (const_tree);
/* Create a mapping from a boolean variable in a method being inlined
to one in the scope of the method being inlined into. */
-static int
-merge_init_test_initialization (void **entry, void *x)
+int
+merge_init_test_initialization (treetreehash_entry **entry, void *x)
{
- struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
+ struct treetreehash_entry *ite = *entry;
splay_tree decl_map = (splay_tree)x;
splay_tree_node n;
tree *init_test_decl;
void
java_inlining_merge_static_initializers (tree fn, void *decl_map)
{
- htab_traverse
- (DECL_FUNCTION_INIT_TEST_TABLE (fn),
- merge_init_test_initialization, decl_map);
+ DECL_FUNCTION_INIT_TEST_TABLE (fn)
+ ->traverse<void *, merge_init_test_initialization> (decl_map);
}
/* Lookup a DECL_FUNCTION_INIT_TEST_TABLE entry in the method we're
from the variable in the inlined class to the corresponding
pre-existing one. */
-static int
-inline_init_test_initialization (void **entry, void *x)
+int
+inline_init_test_initialization (treetreehash_entry **entry, void *x)
{
- struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
+ struct treetreehash_entry *ite = *entry;
splay_tree decl_map = (splay_tree)x;
tree h = java_treetreehash_find
void
java_inlining_map_static_initializers (tree fn, void *decl_map)
{
- htab_traverse
- (DECL_FUNCTION_INIT_TEST_TABLE (fn),
- inline_init_test_initialization, decl_map);
+ DECL_FUNCTION_INIT_TEST_TABLE (fn)
+ ->traverse<void *, inline_init_test_initialization> (decl_map);
}
/* Avoid voluminous output for deep recursion of compound exprs. */
We use the same hashtable for normal optabs and conversion optabs. In
the first case mode2 is forced to VOIDmode. */
-struct GTY(()) libfunc_entry {
+struct GTY((for_user)) libfunc_entry {
int op, mode1, mode2;
rtx libfunc;
};
+/* Descriptor for libfunc_entry. */
+
+struct libfunc_hasher : ggc_hasher<libfunc_entry *>
+{
+ static hashval_t hash (libfunc_entry *);
+ static bool equal (libfunc_entry *, libfunc_entry *);
+};
+
/* Target-dependent globals. */
struct GTY(()) target_libfuncs {
/* SYMBOL_REF rtx's for the library functions that are called
rtx x_libfunc_table[LTI_MAX];
/* Hash table used to convert declarations into nodes. */
- htab_t GTY((param_is (struct libfunc_entry))) x_libfunc_hash;
+ hash_table<libfunc_hasher> *GTY(()) x_libfunc_hash;
};
extern GTY(()) struct target_libfuncs default_target_libfuncs;
+2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
+
+ * objc-act.c: use hash_table instead of hashtab.
+
2014-09-15 Jakub Jelinek <jakub@redhat.com>
* Make-lang.in (check_objc_parallelize): Change to just an upper
/* Store all constructed constant strings in a hash table so that
they get uniqued properly. */
-struct GTY(()) string_descriptor {
+struct GTY((for_user)) string_descriptor {
/* The literal argument . */
tree literal;
tree constructor;
};
-static GTY((param_is (struct string_descriptor))) htab_t string_htab;
+struct objc_string_hasher : ggc_hasher<string_descriptor *>
+{
+ static hashval_t hash (string_descriptor *);
+ static bool equal (string_descriptor *, string_descriptor *);
+};
+
+static GTY(()) hash_table<objc_string_hasher> *string_htab;
FILE *gen_declaration_file;
return build1 (ADDR_EXPR, ptrtype, string);
}
-static hashval_t
-string_hash (const void *ptr)
+hashval_t
+objc_string_hasher::hash (string_descriptor *ptr)
{
- const_tree const str = ((const struct string_descriptor *)ptr)->literal;
+ const_tree const str = ptr->literal;
const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
int i, len = TREE_STRING_LENGTH (str);
hashval_t h = len;
return h;
}
-static int
-string_eq (const void *ptr1, const void *ptr2)
+bool
+objc_string_hasher::equal (string_descriptor *ptr1, string_descriptor *ptr2)
{
- const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
- const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
+ const_tree const str1 = ptr1->literal;
+ const_tree const str2 = ptr2->literal;
int len1 = TREE_STRING_LENGTH (str1);
return (len1 == TREE_STRING_LENGTH (str2)
int length;
tree addr;
struct string_descriptor *desc, key;
- void **loc;
/* We should be passed a STRING_CST. */
gcc_checking_assert (TREE_CODE (string) == STRING_CST);
/* Perhaps we already constructed a constant string just like this one? */
key.literal = string;
- loc = htab_find_slot (string_htab, &key, INSERT);
- desc = (struct string_descriptor *) *loc;
+ string_descriptor **loc = string_htab->find_slot (&key, INSERT);
+ desc = *loc;
if (!desc)
{
alias_name_map = objc_map_alloc_ggc (200);
/* Initialize the hash table used to hold the constant string objects. */
- string_htab = htab_create_ggc (31, string_hash,
- string_eq, NULL);
+ string_htab = hash_table<objc_string_hasher>::create_ggc (31);
}
/* Use the following to add a method to class_method_map or
#include "insn-config.h"
#include "rtl.h"
#include "tree.h"
+#include "tree-hasher.h"
#include "stor-layout.h"
#include "stringpool.h"
#include "varasm.h"
\f
/* Used for libfunc_hash. */
-static hashval_t
-hash_libfunc (const void *p)
+hashval_t
+libfunc_hasher::hash (libfunc_entry *e)
{
- const struct libfunc_entry *const e = (const struct libfunc_entry *) p;
return ((e->mode1 + e->mode2 * NUM_MACHINE_MODES) ^ e->op);
}
/* Used for libfunc_hash. */
-static int
-eq_libfunc (const void *p, const void *q)
+bool
+libfunc_hasher::equal (libfunc_entry *e1, libfunc_entry *e2)
{
- const struct libfunc_entry *const e1 = (const struct libfunc_entry *) p;
- const struct libfunc_entry *const e2 = (const struct libfunc_entry *) q;
return e1->op == e2->op && e1->mode1 == e2->mode1 && e1->mode2 == e2->mode2;
}
e.op = optab;
e.mode1 = mode1;
e.mode2 = mode2;
- slot = (struct libfunc_entry **)
- htab_find_slot (libfunc_hash, &e, NO_INSERT);
+ slot = libfunc_hash->find_slot (&e, NO_INSERT);
if (!slot)
{
const struct convert_optab_libcall_d *d
return NULL;
d->libcall_gen (optab, d->libcall_basename, mode1, mode2);
- slot = (struct libfunc_entry **)
- htab_find_slot (libfunc_hash, &e, NO_INSERT);
+ slot = libfunc_hash->find_slot (&e, NO_INSERT);
if (!slot)
return NULL;
}
e.op = optab;
e.mode1 = mode;
e.mode2 = VOIDmode;
- slot = (struct libfunc_entry **)
- htab_find_slot (libfunc_hash, &e, NO_INSERT);
+ slot = libfunc_hash->find_slot (&e, NO_INSERT);
if (!slot)
{
const struct optab_libcall_d *d
return NULL;
d->libcall_gen (optab, d->libcall_basename, d->libcall_suffix, mode);
- slot = (struct libfunc_entry **)
- htab_find_slot (libfunc_hash, &e, NO_INSERT);
+ slot = libfunc_hash->find_slot (&e, NO_INSERT);
if (!slot)
return NULL;
}
gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
}
-/* A table of previously-created libfuncs, hashed by name. */
-static GTY ((param_is (union tree_node))) htab_t libfunc_decls;
-
/* Hashtable callbacks for libfunc_decls. */
-static hashval_t
-libfunc_decl_hash (const void *entry)
+struct libfunc_decl_hasher : ggc_hasher<tree>
{
- return IDENTIFIER_HASH_VALUE (DECL_NAME ((const_tree) entry));
-}
+ static hashval_t
+ hash (tree entry)
+ {
+ return IDENTIFIER_HASH_VALUE (DECL_NAME (entry));
+ }
-static int
-libfunc_decl_eq (const void *entry1, const void *entry2)
-{
- return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
-}
+ static bool
+ equal (tree decl, tree name)
+ {
+ return DECL_NAME (decl) == name;
+ }
+};
+
+/* A table of previously-created libfuncs, hashed by name. */
+static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls;
/* Build a decl for a libfunc named NAME. */
init_one_libfunc (const char *name)
{
tree id, decl;
- void **slot;
hashval_t hash;
if (libfunc_decls == NULL)
- libfunc_decls = htab_create_ggc (37, libfunc_decl_hash,
- libfunc_decl_eq, NULL);
+ libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37);
/* See if we have already created a libfunc decl for this function. */
id = get_identifier (name);
hash = IDENTIFIER_HASH_VALUE (id);
- slot = htab_find_slot_with_hash (libfunc_decls, id, hash, INSERT);
- decl = (tree) *slot;
+ tree *slot = libfunc_decls->find_slot_with_hash (id, hash, INSERT);
+ decl = *slot;
if (decl == NULL)
{
/* Create a new decl, so that it can be passed to
set_user_assembler_libfunc (const char *name, const char *asmspec)
{
tree id, decl;
- void **slot;
hashval_t hash;
id = get_identifier (name);
hash = IDENTIFIER_HASH_VALUE (id);
- slot = htab_find_slot_with_hash (libfunc_decls, id, hash, NO_INSERT);
+ tree *slot = libfunc_decls->find_slot_with_hash (id, hash, NO_INSERT);
gcc_assert (slot);
decl = (tree) *slot;
set_user_assembler_name (decl, asmspec);
val = init_one_libfunc (name);
else
val = 0;
- slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
+ slot = libfunc_hash->find_slot (&e, INSERT);
if (*slot == NULL)
*slot = ggc_alloc<libfunc_entry> ();
(*slot)->op = op;
val = init_one_libfunc (name);
else
val = 0;
- slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
+ slot = libfunc_hash->find_slot (&e, INSERT);
if (*slot == NULL)
*slot = ggc_alloc<libfunc_entry> ();
(*slot)->op = optab;
init_optabs (void)
{
if (libfunc_hash)
- htab_empty (libfunc_hash);
+ libfunc_hash->empty ();
else
- libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
+ libfunc_hash = hash_table<libfunc_hasher>::create_ggc (10);
/* Fill in the optabs with the insns we support. */
init_all_optabs (this_fn_optabs);
};
/* Information about a section, which may be named or unnamed. */
-union GTY ((desc ("SECTION_STYLE (&(%h))"))) section {
+union GTY ((desc ("SECTION_STYLE (&(%h))"), for_user)) section {
struct section_common GTY ((skip)) common;
struct named_section GTY ((tag ("SECTION_NAMED"))) named;
struct unnamed_section GTY ((tag ("SECTION_UNNAMED"))) unnamed;
/* Describes a group of objects that are to be placed together in such
a way that their relative positions are known. */
-struct GTY(()) object_block {
+struct GTY((for_user)) object_block {
/* The section in which these objects should be placed. */
section *sect;
edge exit_region = SESE_EXIT (region);
basic_block before_region = entry_region->src;
basic_block last_in_region = exit_region->src;
- void **slot = htab_find_slot_with_hash (current_loops->exits, exit_region,
- htab_hash_pointer (exit_region),
- NO_INSERT);
+ hashval_t hash = htab_hash_pointer (exit_region);
+ loop_exit **slot
+ = current_loops->exits->find_slot_with_hash (exit_region, hash, NO_INSERT);
entry_region->flags = false_edge->flags;
false_edge->flags = exit_region->flags;
struct loop_exit *loop_exit = ggc_cleared_alloc<struct loop_exit> ();
memcpy (loop_exit, *((struct loop_exit **) slot), sizeof (struct loop_exit));
- htab_clear_slot (current_loops->exits, slot);
+ current_loops->exits->clear_slot (slot);
- slot = htab_find_slot_with_hash (current_loops->exits, false_edge,
- htab_hash_pointer (false_edge),
- INSERT);
+ hashval_t hash = htab_hash_pointer (false_edge);
+ slot = current_loops->exits->find_slot_with_hash (false_edge, hash,
+ INSERT);
loop_exit->e = false_edge;
*slot = loop_exit;
false_edge->src->loop_father->exits->next = loop_exit;
}
-/* Returns a hash code for P. */
-
-hashval_t
-symbol_table::hash_node_by_assembler_name (const void *p)
-{
- const symtab_node *n = (const symtab_node *) p;
- return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl));
-}
-
/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
bool
/* Returns nonzero if P1 and P2 are equal. */
-int
-symbol_table::eq_assembler_name (const void *p1, const void *p2)
-{
- const symtab_node *n1 = (const symtab_node *) p1;
- const_tree name = (const_tree)p2;
- return (decl_assembler_name_equal (n1->decl, name));
-}
-
/* Insert NODE to assembler name hash. */
void
&& !node->next_sharing_asm_name);
if (assembler_name_hash)
{
- void **aslot;
+ symtab_node **aslot;
cgraph_node *cnode;
tree decl = node->decl;
tree name = DECL_ASSEMBLER_NAME (node->decl);
- aslot = htab_find_slot_with_hash (assembler_name_hash, name,
- decl_assembler_name_hash (name),
- INSERT);
+ hashval_t hash = decl_assembler_name_hash (name);
+ aslot = assembler_name_hash->find_slot_with_hash (name, hash, INSERT);
gcc_assert (*aslot != node);
node->next_sharing_asm_name = (symtab_node *)*aslot;
if (*aslot != NULL)
- ((symtab_node *)*aslot)->previous_sharing_asm_name = node;
+ (*aslot)->previous_sharing_asm_name = node;
*aslot = node;
/* Update also possible inline clones sharing a decl. */
else
{
tree name = DECL_ASSEMBLER_NAME (node->decl);
- void **slot;
- slot = htab_find_slot_with_hash (assembler_name_hash, name,
- decl_assembler_name_hash (name),
- NO_INSERT);
+ symtab_node **slot;
+ hashval_t hash = decl_assembler_name_hash (name);
+ slot = assembler_name_hash->find_slot_with_hash (name, hash,
+ NO_INSERT);
gcc_assert (*slot == node);
if (!node->next_sharing_asm_name)
- htab_clear_slot (assembler_name_hash, slot);
+ assembler_name_hash->clear_slot (slot);
else
*slot = node->next_sharing_asm_name;
}
symtab_node *node;
if (!assembler_name_hash)
{
- assembler_name_hash =
- htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
- NULL);
+ assembler_name_hash = hash_table<asmname_hasher>::create_ggc (10);
FOR_EACH_SYMBOL (node)
insert_to_assembler_name_hash (node, false);
}
/* Hash sections by their names. */
-static hashval_t
-hash_section_hash_entry (const void *p)
+hashval_t
+section_name_hasher::hash (section_hash_entry *n)
{
- const section_hash_entry *n = (const section_hash_entry *) p;
return htab_hash_string (n->name);
}
/* Return true if section P1 name equals to P2. */
-static int
-eq_sections (const void *p1, const void *p2)
+bool
+section_name_hasher::equal (section_hash_entry *n1, const char *name)
{
- const section_hash_entry *n1 = (const section_hash_entry *) p1;
- const char *name = (const char *)p2;
return n1->name == name || !strcmp (n1->name, name);
}
symtab_node::get_for_asmname (const_tree asmname)
{
symtab_node *node;
- void **slot;
symtab->symtab_initialize_asm_name_hash ();
- slot = htab_find_slot_with_hash (symtab->assembler_name_hash, asmname,
- symtab->decl_assembler_name_hash (asmname),
- NO_INSERT);
+ hashval_t hash = symtab->decl_assembler_name_hash (asmname);
+ symtab_node **slot
+ = symtab->assembler_name_hash->find_slot_with_hash (asmname, hash,
+ NO_INSERT);
if (slot)
{
- node = (symtab_node *) *slot;
+ node = *slot;
return node;
}
return NULL;
symtab_node::set_section_for_node (const char *section)
{
const char *current = get_section ();
- void **slot;
+ section_hash_entry **slot;
if (current == section
|| (current && section
x_section->ref_count--;
if (!x_section->ref_count)
{
- slot = htab_find_slot_with_hash (symtab->section_hash, x_section->name,
- htab_hash_string (x_section->name),
- INSERT);
+ hashval_t hash = htab_hash_string (x_section->name);
+ slot = symtab->section_hash->find_slot_with_hash (x_section->name,
+ hash, INSERT);
ggc_free (x_section);
- htab_clear_slot (symtab->section_hash, slot);
+ symtab->section_hash->clear_slot (slot);
}
x_section = NULL;
}
return;
}
if (!symtab->section_hash)
- symtab->section_hash = htab_create_ggc (10, hash_section_hash_entry,
- eq_sections, NULL);
- slot = htab_find_slot_with_hash (symtab->section_hash, section,
- htab_hash_string (section),
- INSERT);
+ symtab->section_hash = hash_table<section_name_hasher>::create_ggc (10);
+ slot = symtab->section_hash->find_slot_with_hash (section,
+ htab_hash_string (section),
+ INSERT);
if (*slot)
x_section = (section_hash_entry *)*slot;
else
if (loops_for_fn (saved_cfun)->exits)
FOR_EACH_EDGE (e, ei, bb->succs)
{
- void **slot = htab_find_slot_with_hash
- (loops_for_fn (saved_cfun)->exits, e,
- htab_hash_pointer (e), NO_INSERT);
+ struct loops *l = loops_for_fn (saved_cfun);
+ loop_exit **slot
+ = l->exits->find_slot_with_hash (e, htab_hash_pointer (e),
+ NO_INSERT);
if (slot)
- htab_clear_slot (loops_for_fn (saved_cfun)->exits, slot);
+ l->exits->clear_slot (slot);
}
}
|| TREE_CODE (var) == RESULT_DECL);
in.var = (tree)&ind;
ind.uid = DECL_UID (var);
- return (tree) htab_find_with_hash (DEFAULT_DEFS (fn), &in, DECL_UID (var));
+ return DEFAULT_DEFS (fn)->find_with_hash ((tree)&in, DECL_UID (var));
}
/* Insert the pair VAR's UID, DEF into the default_defs hashtable
{
struct tree_decl_minimal ind;
struct tree_ssa_name in;
- void **loc;
gcc_assert (TREE_CODE (var) == VAR_DECL
|| TREE_CODE (var) == PARM_DECL
ind.uid = DECL_UID (var);
if (!def)
{
- loc = htab_find_slot_with_hash (DEFAULT_DEFS (fn), &in,
- DECL_UID (var), NO_INSERT);
+ tree *loc = DEFAULT_DEFS (fn)->find_slot_with_hash ((tree)&in,
+ DECL_UID (var),
+ NO_INSERT);
if (loc)
{
SSA_NAME_IS_DEFAULT_DEF (*(tree *)loc) = false;
- htab_clear_slot (DEFAULT_DEFS (fn), loc);
+ DEFAULT_DEFS (fn)->clear_slot (loc);
}
return;
}
gcc_assert (TREE_CODE (def) == SSA_NAME && SSA_NAME_VAR (def) == var);
- loc = htab_find_slot_with_hash (DEFAULT_DEFS (fn), &in,
- DECL_UID (var), INSERT);
+ tree *loc = DEFAULT_DEFS (fn)->find_slot_with_hash ((tree)&in,
+ DECL_UID (var), INSERT);
/* Default definition might be changed by tail call optimization. */
if (*loc)
- SSA_NAME_IS_DEFAULT_DEF (*(tree *) loc) = false;
+ SSA_NAME_IS_DEFAULT_DEF (*loc) = false;
/* Mark DEF as the default definition for VAR. */
- *(tree *) loc = def;
+ *loc = def;
SSA_NAME_IS_DEFAULT_DEF (def) = true;
}
internal_error ("verify_ssa failed");
}
-/* Return true if the DECL_UID in both trees are equal. */
-
-static int
-uid_ssaname_map_eq (const void *va, const void *vb)
-{
- const_tree a = (const_tree) va;
- const_tree b = (const_tree) vb;
- return (a->ssa_name.var->decl_minimal.uid == b->ssa_name.var->decl_minimal.uid);
-}
-
-/* Hash a tree in a uid_decl_map. */
-
-static unsigned int
-uid_ssaname_map_hash (const void *item)
-{
- return ((const_tree)item)->ssa_name.var->decl_minimal.uid;
-}
-
/* Initialize global DFA and SSA structures. */
init_tree_ssa (struct function *fn)
{
fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
- fn->gimple_df->default_defs = htab_create_ggc (20, uid_ssaname_map_hash,
- uid_ssaname_map_eq, NULL);
+ fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
pt_solution_reset (&fn->gimple_df->escaped);
init_ssanames (fn, 0);
}
if (ssa_operands_active (cfun))
fini_ssa_operands (cfun);
- htab_delete (cfun->gimple_df->default_defs);
+ cfun->gimple_df->default_defs->empty ();
cfun->gimple_df->default_defs = NULL;
pt_solution_reset (&cfun->gimple_df->escaped);
if (cfun->gimple_df->decls_to_pointers != NULL)
static bool incorporeal_function_p (tree);
#endif
static void decode_addr_const (tree, struct addr_const *);
-static hashval_t const_desc_hash (const void *);
-static int const_desc_eq (const void *, const void *);
static hashval_t const_hash_1 (const tree);
static int compare_constant (const tree, const tree);
static void output_constant_def_contents (rtx);
((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
&& DECL_SECTION_NAME (DECL) != NULL)
+struct section_hasher : ggc_hasher<section *>
+{
+ typedef const char *compare_type;
+
+ static hashval_t hash (section *);
+ static bool equal (section *, const char *);
+};
+
/* Hash table of named sections. */
-static GTY((param_is (section))) htab_t section_htab;
+static GTY(()) hash_table<section_hasher> *section_htab;
+
+struct object_block_hasher : ggc_hasher<object_block *>
+{
+ typedef const section *compare_type;
+
+ static hashval_t hash (object_block *);
+ static bool equal (object_block *, const section *);
+};
/* A table of object_blocks, indexed by section. */
-static GTY((param_is (struct object_block))) htab_t object_block_htab;
+static GTY(()) hash_table<object_block_hasher> *object_block_htab;
/* The next number to use for internal anchor labels. */
static GTY(()) int anchor_labelno;
/* Helper routines for maintaining section_htab. */
-static int
-section_entry_eq (const void *p1, const void *p2)
+bool
+section_hasher::equal (section *old, const char *new_name)
{
- const section *old = (const section *) p1;
- const char *new_name = (const char *) p2;
-
return strcmp (old->named.name, new_name) == 0;
}
-static hashval_t
-section_entry_hash (const void *p)
+hashval_t
+section_hasher::hash (section *old)
{
- const section *old = (const section *) p;
return htab_hash_string (old->named.name);
}
/* Helper routines for maintaining object_block_htab. */
-static int
-object_block_entry_eq (const void *p1, const void *p2)
+inline bool
+object_block_hasher::equal (object_block *old, const section *new_section)
{
- const struct object_block *old = (const struct object_block *) p1;
- const section *new_section = (const section *) p2;
-
return old->sect == new_section;
}
-static hashval_t
-object_block_entry_hash (const void *p)
+hashval_t
+object_block_hasher::hash (object_block *old)
{
- const struct object_block *old = (const struct object_block *) p;
return hash_section (old->sect);
}
{
section *sect, **slot;
- slot = (section **)
- htab_find_slot_with_hash (section_htab, name,
- htab_hash_string (name), INSERT);
+ slot = section_htab->find_slot_with_hash (name, htab_hash_string (name),
+ INSERT);
flags |= SECTION_NAMED;
if (*slot == NULL)
{
get_block_for_section (section *sect)
{
struct object_block *block;
- void **slot;
if (sect == NULL)
return NULL;
- slot = htab_find_slot_with_hash (object_block_htab, sect,
- hash_section (sect), INSERT);
- block = (struct object_block *) *slot;
+ object_block **slot
+ = object_block_htab->find_slot_with_hash (sect, hash_section (sect),
+ INSERT);
+ block = *slot;
if (block == NULL)
{
block = ggc_cleared_alloc<object_block> ();
value->offset = offset;
}
\f
-
-static GTY((param_is (struct constant_descriptor_tree)))
- htab_t const_desc_htab;
+static GTY(()) hash_table<tree_descriptor_hasher> *const_desc_htab;
static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int);
/* Constant pool accessor function. */
-htab_t
+hash_table<tree_descriptor_hasher> *
constant_pool_htab (void)
{
return const_desc_htab;
/* Compute a hash code for a constant expression. */
-static hashval_t
-const_desc_hash (const void *ptr)
+hashval_t
+tree_descriptor_hasher::hash (constant_descriptor_tree *ptr)
{
- return ((const struct constant_descriptor_tree *)ptr)->hash;
+ return ptr->hash;
}
static hashval_t
}
/* Wrapper of compare_constant, for the htab interface. */
-static int
-const_desc_eq (const void *p1, const void *p2)
+bool
+tree_descriptor_hasher::equal (constant_descriptor_tree *c1,
+ constant_descriptor_tree *c2)
{
- const struct constant_descriptor_tree *const c1
- = (const struct constant_descriptor_tree *) p1;
- const struct constant_descriptor_tree *const c2
- = (const struct constant_descriptor_tree *) p2;
if (c1->hash != c2->hash)
return 0;
return compare_constant (c1->value, c2->value);
{
struct constant_descriptor_tree *desc;
struct constant_descriptor_tree key;
- void **loc;
/* Look up EXP in the table of constant descriptors. If we didn't find
it, create a new one. */
key.value = exp;
key.hash = const_hash_1 (exp);
- loc = htab_find_slot_with_hash (const_desc_htab, &key, key.hash, INSERT);
+ constant_descriptor_tree **loc
+ = const_desc_htab->find_slot_with_hash (&key, key.hash, INSERT);
- desc = (struct constant_descriptor_tree *) *loc;
+ desc = *loc;
if (desc == 0)
{
desc = build_constant_desc (exp);
rtx
lookup_constant_def (tree exp)
{
- struct constant_descriptor_tree *desc;
struct constant_descriptor_tree key;
key.value = exp;
key.hash = const_hash_1 (exp);
- desc = (struct constant_descriptor_tree *)
- htab_find_with_hash (const_desc_htab, &key, key.hash);
+ constant_descriptor_tree *desc
+ = const_desc_htab->find_with_hash (&key, key.hash);
return (desc ? desc->rtl : NULL_RTX);
}
tree_output_constant_def (tree exp)
{
struct constant_descriptor_tree *desc, key;
- void **loc;
tree decl;
/* Look up EXP in the table of constant descriptors. If we didn't find
it, create a new one. */
key.value = exp;
key.hash = const_hash_1 (exp);
- loc = htab_find_slot_with_hash (const_desc_htab, &key, key.hash, INSERT);
+ constant_descriptor_tree **loc
+ = const_desc_htab->find_slot_with_hash (&key, key.hash, INSERT);
- desc = (struct constant_descriptor_tree *) *loc;
+ desc = *loc;
if (desc == 0)
{
desc = build_constant_desc (exp);
return decl;
}
\f
+struct GTY((chain_next ("%h.next"), for_user)) constant_descriptor_rtx {
+ struct constant_descriptor_rtx *next;
+ rtx mem;
+ rtx sym;
+ rtx constant;
+ HOST_WIDE_INT offset;
+ hashval_t hash;
+ enum machine_mode mode;
+ unsigned int align;
+ int labelno;
+ int mark;
+};
+
+struct const_rtx_desc_hasher : ggc_hasher<constant_descriptor_rtx *>
+{
+ static hashval_t hash (constant_descriptor_rtx *);
+ static bool equal (constant_descriptor_rtx *, constant_descriptor_rtx *);
+};
+
/* Used in the hash tables to avoid outputting the same constant
twice. Unlike 'struct constant_descriptor_tree', RTX constants
are output once per function, not once per file. */
It is used on RISC machines where immediate integer arguments and
constant addresses are restricted so that such constants must be stored
in memory. */
- htab_t GTY((param_is (struct constant_descriptor_rtx))) const_rtx_htab;
+ hash_table<const_rtx_desc_hasher> *const_rtx_htab;
/* Current offset in constant pool (does not include any
machine-specific header). */
HOST_WIDE_INT offset;
};
-struct GTY((chain_next ("%h.next"))) constant_descriptor_rtx {
- struct constant_descriptor_rtx *next;
- rtx mem;
- rtx sym;
- rtx constant;
- HOST_WIDE_INT offset;
- hashval_t hash;
- enum machine_mode mode;
- unsigned int align;
- int labelno;
- int mark;
-};
-
/* Hash and compare functions for const_rtx_htab. */
-static hashval_t
-const_desc_rtx_hash (const void *ptr)
+hashval_t
+const_rtx_desc_hasher::hash (constant_descriptor_rtx *desc)
{
- const struct constant_descriptor_rtx *const desc
- = (const struct constant_descriptor_rtx *) ptr;
return desc->hash;
}
-static int
-const_desc_rtx_eq (const void *a, const void *b)
+bool
+const_rtx_desc_hasher::equal (constant_descriptor_rtx *x,
+ constant_descriptor_rtx *y)
{
- const struct constant_descriptor_rtx *const x
- = (const struct constant_descriptor_rtx *) a;
- const struct constant_descriptor_rtx *const y
- = (const struct constant_descriptor_rtx *) b;
-
if (x->mode != y->mode)
return 0;
return rtx_equal_p (x->constant, y->constant);
struct rtx_constant_pool *pool;
pool = ggc_alloc<rtx_constant_pool> ();
- pool->const_rtx_htab = htab_create_ggc (31, const_desc_rtx_hash,
- const_desc_rtx_eq, NULL);
+ pool->const_rtx_htab = hash_table<const_rtx_desc_hasher>::create_ggc (31);
pool->first = NULL;
pool->last = NULL;
pool->offset = 0;
rtx def, symbol;
hashval_t hash;
unsigned int align;
- void **slot;
+ constant_descriptor_rtx **slot;
/* If we're not allowed to drop X into the constant pool, don't. */
if (targetm.cannot_force_const_mem (mode, x))
tmp.constant = x;
tmp.mode = mode;
hash = const_rtx_hash (x);
- slot = htab_find_slot_with_hash (pool->const_rtx_htab, &tmp, hash, INSERT);
- desc = (struct constant_descriptor_rtx *) *slot;
+ slot = pool->const_rtx_htab->find_slot_with_hash (&tmp, hash, INSERT);
+ desc = *slot;
/* If the constant was already present, return its memory. */
if (desc)
void
init_varasm_once (void)
{
- section_htab = htab_create_ggc (31, section_entry_hash,
- section_entry_eq, NULL);
- object_block_htab = htab_create_ggc (31, object_block_entry_hash,
- object_block_entry_eq, NULL);
- const_desc_htab = htab_create_ggc (1009, const_desc_hash,
- const_desc_eq, NULL);
+ section_htab = hash_table<section_hasher>::create_ggc (31);
+ object_block_htab = hash_table<object_block_hasher>::create_ggc (31);
+ const_desc_htab = hash_table<tree_descriptor_hasher>::create_ggc (1009);
const_alias_set = new_alias_set ();
shared_constant_pool = create_constant_pool ();
/* A htab_traverse callback used to call output_object_block for
each member of object_block_htab. */
-static int
-output_object_block_htab (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+output_object_block_htab (object_block **slot, void *)
{
- output_object_block ((struct object_block *) (*slot));
+ output_object_block (*slot);
return 1;
}
void
output_object_blocks (void)
{
- htab_traverse (object_block_htab, output_object_block_htab, NULL);
+ object_block_htab->traverse<void *, output_object_block_htab> (NULL);
}
/* This function provides a possible implementation of the