diff options
author | Neil Booth <neil@daikokuya.demon.co.uk> | 2001-05-20 06:26:45 +0000 |
---|---|---|
committer | Neil Booth <neil@gcc.gnu.org> | 2001-05-20 06:26:45 +0000 |
commit | 2a967f3d3a45294640e155381ef549e0b8090ad4 (patch) | |
tree | 31a2cc3c54959e2908bad78e488472f5e3ce3d69 /gcc/cpphash.c | |
parent | 9e800206badd2be563d344e4a0aee83e3ac96f03 (diff) | |
download | gcc-2a967f3d3a45294640e155381ef549e0b8090ad4.zip gcc-2a967f3d3a45294640e155381ef549e0b8090ad4.tar.gz gcc-2a967f3d3a45294640e155381ef549e0b8090ad4.tar.bz2 |
Makefile.in (OBJS, [...]): Update.
* Makefile.in (OBJS, LIBCPP_OBJS, LIBCPP_DEPS,
cpplib.o, cpphash.o, fix-header): Update.
(hashtable.o): New target.
* c-common.h: Include cpplib.h. Define C_RID_CODE and
struct c_common_identifier here.
* c-lang.c (c_init_options): Update. Call set_identifier_size.
* c-lex.c (c_lex): Update.
* c-pragma.h: Update.
* c-tree.h (struct lang_identifier): Contain c_common_identifier.
Delete rid_code.
(C_RID_CODE): Delete.
* cpphash.c: Rewrite to use hashtable.c.
* cpphash.h: Update include guards.
(struct cpp_reader): Remove hashtab.
hash_ob and buffer_ob are no longer pointers. Add hash_table
and our_hashtable.
(HASHSTEP, _cpp_init_hashtable, _cpp_lookup_with_hash): Delete.
(_cpp_cleanup_hashtable): Rename _cpp_destroy_hashtable.
(_cpp_cleanup_stacks): Rename _cpp_init_directives.
* cppinit.c (cpp_create_reader): Update.
* cpplex.c (cpp_ideq, parse_identifier, cpp_output_token): Update.
(cpp_interpret_charconst): Eliminate warning.
* cpplib.c (do_pragma, do_endif, push_conditional,
cpp_push_buffer, cpp_pop_buffer): Update.
(_cpp_init_stacks): Rename cpp_init_directives.
(_cpp_cleanup_stacks): Remove.
* cpplib.h: Update include guards. Include tree-core.h and c-rid.h.
(cpp_hashnode, cpp_token, NODE_LEN, NODE_NAME,
cpp_forall_identifiers, cpp_create_reader): Update.
(C_RID_CODE, cpp_make_node): New.
(c_common_identifier): New identifier node for C front ends.
* cppmain.c (main): Update.
* fix-header.c (read_scan_file): Update.
* flags.h (id_clash_len): Make unsigned.
* ggc.h (ggc_mark_nonnull_tree): New.
* hashtable.c: New.
* hashtable.h: New.
* stringpool.c: Update comments and copyright. Update to use
hashtable.c.
* toplev.c (approx_sqrt): Move to hashtable.c.
(id_clash_len): Make unsigned.
* toplev.h (ident_hash): New.
* tree.c (gcc_obstack_init): Move to hashtable.c.
* tree.h: Include hashtable.h.
(IDENTIFIER_POINTER, IDENTIFIER_LENGTH): Update.
(GCC_IDENT_TO_HT_IDENT, HT_IDENT_TO_GCC_IDENT): New.
(struct tree_identifier): Update.
(make_identifier): New.
cp:
* cp-tree.h (struct lang_identifier, C_RID_YYCODE): Update.
(C_RID_CODE): Remove.
* lex.c (cxx_init_options): Call set_identifier_size. Update.
(init_parse): Don't do it here.
objc:
* objc-act.c (objc_init_options): Call set_identifier_size. Update.
From-SVN: r42334
Diffstat (limited to 'gcc/cpphash.c')
-rw-r--r-- | gcc/cpphash.c | 283 |
1 files changed, 56 insertions, 227 deletions
diff --git a/gcc/cpphash.c b/gcc/cpphash.c index a47a635..9383c27 100644 --- a/gcc/cpphash.c +++ b/gcc/cpphash.c @@ -1,4 +1,4 @@ -/* Part of CPP library. (Identifier and string tables.) +/* Hash tables for the CPP library. Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000 Free Software Foundation, Inc. Written by Per Bothner, 1994. @@ -27,266 +27,95 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "system.h" #include "cpplib.h" #include "cpphash.h" -#include "obstack.h" -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free +static cpp_hashnode *alloc_node PARAMS ((hash_table *)); -/* Initial hash table size. (It can grow if necessary.) This is the - largest prime number smaller than 2**12. */ -#define HASHSIZE 4093 +/* Return an identifier node for hashtable.c. Used by cpplib except + when integrated with the C front ends. */ -/* This is the structure used for the hash table. */ -struct htab +static cpp_hashnode * +alloc_node (table) + hash_table *table; { - struct cpp_hashnode **entries; - size_t size; - size_t nelts; -}; - -static void expand_hash PARAMS ((struct htab *)); -static unsigned long higher_prime_number PARAMS ((unsigned long)); - -/* Set up and tear down internal structures for macro expansion. */ -void -_cpp_init_hashtable (pfile) - cpp_reader *pfile; -{ - pfile->hash_ob = xnew (struct obstack); - obstack_init (pfile->hash_ob); - - pfile->hashtab = xobnew (pfile->hash_ob, struct htab); - - pfile->hashtab->nelts = 0; - pfile->hashtab->size = HASHSIZE; - pfile->hashtab->entries = xcnewvec (cpp_hashnode *, HASHSIZE); + cpp_hashnode *node; + + node = obstack_alloc (&table->pfile->hash_ob, sizeof (cpp_hashnode)); + memset ((PTR) node, 0, sizeof (cpp_hashnode)); + return node; } +/* Set up the identifier hash table. Use TABLE if non-null, otherwise + create our own. */ + void -_cpp_cleanup_hashtable (pfile) +_cpp_init_hashtable (pfile, table) cpp_reader *pfile; + hash_table *table; { - cpp_hashnode **p, **limit; - - p = pfile->hashtab->entries; - limit = p + pfile->hashtab->size; - do + if (table == NULL) { - if (*p) - _cpp_free_definition (*p); + pfile->our_hashtable = 1; + table = ht_create (13); /* 8K (=2^13) entries. */ + table->alloc_node = (hashnode (*) PARAMS ((hash_table *))) alloc_node; + gcc_obstack_init (&pfile->hash_ob); } - while (++p < limit); - free (pfile->hashtab->entries); - obstack_free (pfile->hash_ob, 0); - free (pfile->hash_ob); + table->pfile = pfile; + pfile->hash_table = table; } -/* The code below is a specialization of Vladimir Makarov's expandable - hash tables (see libiberty/hashtab.c). The abstraction penalty was - too high to continue using the generic form. This code knows - intrinsically how to calculate a hash value, and how to compare an - existing entry with a potential new one. Also, the ability to - delete members from the table has been removed. */ +/* Tear down the identifier hash table. */ -cpp_hashnode * -cpp_lookup (pfile, name, len) +void +_cpp_destroy_hashtable (pfile) cpp_reader *pfile; - const U_CHAR *name; - size_t len; { - size_t n = len; - unsigned int r = 0; - const U_CHAR *str = name; - U_CHAR *dest = _cpp_pool_reserve (&pfile->ident_pool, len + 1); - - do + if (pfile->our_hashtable) { - r = HASHSTEP (r, *str); - *dest++ = *str++; + free (pfile->hash_table); + obstack_free (&pfile->hash_ob, 0); } - while (--n); - *dest = '\0'; - - return _cpp_lookup_with_hash (pfile, len, r); } -/* NAME is a null-terminated identifier of length len. It is assumed - to have been placed at the front of the identifier pool. */ +/* Returns the hash entry for the STR of length LEN, creating one + if necessary. */ + cpp_hashnode * -_cpp_lookup_with_hash (pfile, len, hash) +cpp_lookup (pfile, str, len) cpp_reader *pfile; - size_t len; - unsigned int hash; -{ - unsigned int index; - size_t size; - cpp_hashnode *entry; - cpp_hashnode **entries; - unsigned char *name = POOL_FRONT (&pfile->ident_pool); - - entries = pfile->hashtab->entries; - size = pfile->hashtab->size; - - hash += len; - index = hash % size; - - entry = entries[index]; - if (entry) - { - unsigned int hash2; - - if (entry->hash == hash && NODE_LEN (entry) == len - && !memcmp (NODE_NAME (entry), name, len)) - return entry; - - hash2 = 1 + hash % (size - 2); - - for (;;) - { - index += hash2; - if (index >= size) - index -= size; - entry = entries[index]; - - if (entry == NULL) - break; - if (entry->hash == hash && NODE_LEN (entry) == len - && !memcmp (NODE_NAME (entry), name, len)) - return entry; - } - } - - /* Commit the memory for the identifier. */ - POOL_COMMIT (&pfile->ident_pool, len + 1); - - /* Create a new hash node and insert it in the table. */ - entries[index] = obstack_alloc (pfile->hash_ob, sizeof (cpp_hashnode)); - - entry = entries[index]; - entry->type = NT_VOID; - entry->flags = 0; - entry->directive_index = 0; - entry->arg_index = 0; - NODE_LEN (entry) = len; - entry->hash = hash; - NODE_NAME (entry) = name; - entry->value.macro = 0; - - pfile->hashtab->nelts++; - if (size * 3 <= pfile->hashtab->nelts * 4) - expand_hash (pfile->hashtab); - - return entry; -} - -static void -expand_hash (htab) - struct htab *htab; + const unsigned char *str; + unsigned int len; { - cpp_hashnode **oentries; - cpp_hashnode **olimit; - cpp_hashnode **p; - size_t size; - - oentries = htab->entries; - olimit = oentries + htab->size; - - htab->size = size = higher_prime_number (htab->size * 2); - htab->entries = xcnewvec (cpp_hashnode *, size); - - for (p = oentries; p < olimit; p++) - { - if (*p != NULL) - { - unsigned int index; - unsigned int hash, hash2; - cpp_hashnode *entry = *p; - - hash = entry->hash; - index = hash % size; - - if (htab->entries[index] == NULL) - { - insert: - htab->entries[index] = entry; - continue; - } - - hash2 = 1 + hash % (size - 2); - for (;;) - { - index += hash2; - if (index >= size) - index -= size; - - if (htab->entries[index] == NULL) - goto insert; - } - } - } - - free (oentries); + /* ht_lookup cannot return NULL. */ + return CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_ALLOC)); } -/* The following function returns the nearest prime number which is - greater than a given source number, N. */ +/* Determine whether the str STR, of length LEN, is a defined macro. */ -static unsigned long -higher_prime_number (n) - unsigned long n; +int +cpp_defined (pfile, str, len) + cpp_reader *pfile; + const unsigned char *str; + int len; { - unsigned long i; - - /* Ensure we have a larger number and then force to odd. */ - n++; - n |= 0x01; + cpp_hashnode *node; - /* All odd numbers < 9 are prime. */ - if (n < 9) - return n; + node = CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_NO_INSERT)); - /* Otherwise find the next prime using a sieve. */ - - next: - for (i = 3; i * i <= n; i += 2) - if (n % i == 0) - { - n += 2; - goto next; - } - - return n; + /* If it's of type NT_MACRO, it cannot be poisoned. */ + return node && node->type == NT_MACRO; } +/* For all nodes in the hashtable, callback CB with parameters PFILE, + the node, and V. */ + void cpp_forall_identifiers (pfile, cb, v) cpp_reader *pfile; - int (*cb) PARAMS ((cpp_reader *, cpp_hashnode *, void *)); - void *v; + cpp_cb cb; + PTR v; { - cpp_hashnode **p, **limit; - - p = pfile->hashtab->entries; - limit = p + pfile->hashtab->size; - do - { - if (*p) - if ((*cb) (pfile, *p, v) == 0) - break; - } - while (++p < limit); -} - -/* Determine whether the identifier ID, of length LEN, is a defined macro. */ -int -cpp_defined (pfile, id, len) - cpp_reader *pfile; - const U_CHAR *id; - int len; -{ - cpp_hashnode *hp = cpp_lookup (pfile, id, len); - - /* If it's of type NT_MACRO, it cannot be poisoned. */ - return hp->type == NT_MACRO; + /* We don't need a proxy since the hash table's identifier comes + first in cpp_hashnode. */ + ht_forall (pfile->hash_table, (ht_cb) cb, v); } |