diff options
author | Zack Weinberg <zack@wolery.cumb.org> | 2000-03-12 23:46:05 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 2000-03-12 23:46:05 +0000 |
commit | d35364d13e14ba0eea541a77484c716f1cf82195 (patch) | |
tree | a98d122ee7a482f328ecd041626122a0cd1beaa8 /gcc/cpphash.c | |
parent | 6973bf5482d8a5a150c3ee1424bf7e154e61dd51 (diff) | |
download | gcc-d35364d13e14ba0eea541a77484c716f1cf82195.zip gcc-d35364d13e14ba0eea541a77484c716f1cf82195.tar.gz gcc-d35364d13e14ba0eea541a77484c716f1cf82195.tar.bz2 |
Convert cpplib to use libiberty/hashtab.c.
* cpplib.h (struct cpp_reader): Make hashtab and
all_include_files of type 'struct htab *'. Delete HASHSIZE
and ALL_INCLUDE_HASHSIZE macros.
* cpphash.h: Update prototypes.
(struct hashnode): Remove next, prev, and bucket_hdr members.
Make length a size_t. Add hash member.
(struct ihash): Remove next member. Add hash member. Make
name a flexible array member.
* cppfiles.c: Include hashtab.h.
(include_hash): Delete.
(IHASHSIZE): New macro.
(hash_IHASH, eq_IHASH, _cpp_init_include_hash): New functions.
(cpp_included): Do the hash lookup here.
(_cpp_find_include_file): Rewrite.
(cpp_read_file): Put the "fake" hash entry into the hash
table. Honor the control_macro, if it turns out we've seen
the file before. Don't push the buffer here.
(_cpp_read_include_file): Push the buffer here.
(OMODES): New macro. Use it whenever we call open(2).
* cpphash.c: Include hashtab.h.
(hash_HASHNODE, eq_HASHNODE, del_HASHNODE, dump_hash_helper,
_cpp_init_macro_hash, _cpp_dump_macro_hash, _cpp_make_hashnode,
_cpp_lookup_slot): New functions.
(HASHSIZE): new macro.
(hashf, _cpp_install, _cpp_delete_macro): Delete.
(_cpp_lookup): Use hashtab.h routines.
* cppinit.c: Include hashtab.h.
(cpp_reader_init): Call _cpp_init_macro_hash and
_cpp_init_include_hash. Don't allocate hashtab directly.
(cpp_cleanup): Just call htab_delete on pfile->hashtab and
pfile->all_include_files.
(initialize_builtins): Use _cpp_make_hashnode and
htab_find_slot to add hash entries.
(cpp_finish): Just call _cpp_dump_macro_hash.
* cpplib.c: Include hashtab.h.
(do_define): Use _cpp_lookup_slot and _cpp_make_hashnode to
create hash entries.
(do_pragma_poison, do_assert): Likewise.
(do_include): Don't push the buffer here. Don't increment
system_include_depth unless _cpp_read_include_file succeeds.
(do_undef, do_unassert): Use _cpp_lookup_slot and htab_clear_slot
or htab_remove_elt.
(do_pragma_implementation): Use alloca to create copy.
* Makefile.in: Update dependencies.
From-SVN: r32497
Diffstat (limited to 'gcc/cpphash.c')
-rw-r--r-- | gcc/cpphash.c | 240 |
1 files changed, 135 insertions, 105 deletions
diff --git a/gcc/cpphash.c b/gcc/cpphash.c index e81b221..f993510 100644 --- a/gcc/cpphash.c +++ b/gcc/cpphash.c @@ -27,10 +27,15 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "system.h" #include "cpplib.h" #include "cpphash.h" +#include "hashtab.h" #include "version.h" #undef abort -static unsigned int hashf PARAMS ((const U_CHAR *, int)); +static unsigned int hash_HASHNODE PARAMS ((const void *)); +static int eq_HASHNODE PARAMS ((const void *, const void *)); +static void del_HASHNODE PARAMS ((void *)); +static int dump_hash_helper PARAMS ((void *, void *)); + static int comp_def_part PARAMS ((int, U_CHAR *, int, U_CHAR *, int, int)); static void push_macro_expansion PARAMS ((cpp_reader *, @@ -45,6 +50,9 @@ static void special_symbol PARAMS ((HASHNODE *, cpp_reader *)); #define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N)) #define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile)) +/* Initial hash table size. (It can grow if necessary - see hashtab.c.) */ +#define HASHSIZE 500 + /* The arglist structure is built by create_definition to tell collect_expansion where the argument names begin. That is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist @@ -92,28 +100,81 @@ struct argdata int stringified_length; }; - -/* Calculate hash function on a string. */ - +/* Calculate hash of a HASHNODE structure. */ static unsigned int -hashf (s, len) - register const U_CHAR *s; - register int len; +hash_HASHNODE (x) + const void *x; { - unsigned int n = len; - unsigned int r = 0; + HASHNODE *h = (HASHNODE *)x; + const U_CHAR *s = h->name; + unsigned int len = h->length; + unsigned int n = len, r = 0; + if (h->hash != (unsigned long)-1) + return h->hash; + do r = r * 67 + (*s++ - 113); while (--n); + h->hash = r + len; return r + len; } -/* Find the most recent hash node for name "name" (ending with first - non-identifier char) installed by cpp_install +/* Compare two HASHNODE structures. */ +static int +eq_HASHNODE (x, y) + const void *x; + const void *y; +{ + const HASHNODE *a = (const HASHNODE *)x; + const HASHNODE *b = (const HASHNODE *)y; + + return (a->length == b->length + && !strncmp (a->name, b->name, a->length)); +} + +/* Destroy a HASHNODE. */ +static void +del_HASHNODE (x) + void *x; +{ + HASHNODE *h = (HASHNODE *)x; + + if (h->type == T_MACRO) + _cpp_free_definition (h->value.defn); + free ((void *) h->name); + free (h); +} + +/* Allocate and initialize a HASHNODE structure. + Caller must fill in the value field. */ + +HASHNODE * +_cpp_make_hashnode (name, len, type, hash) + const U_CHAR *name; + size_t len; + enum node_type type; + unsigned long hash; +{ + HASHNODE *hp = (HASHNODE *) xmalloc (sizeof (HASHNODE)); + U_CHAR *p = xmalloc (len + 1); + + hp->type = type; + hp->length = len; + hp->name = p; + hp->hash = hash; + + memcpy (p, name, len); + p[len] = 0; + + return hp; +} + +/* Find the hash node for name "name", which ends at the first + non-identifier char. If LEN is >= 0, it is the length of the name. - Otherwise, compute the length by scanning the entire name. */ + Otherwise, compute the length now. */ HASHNODE * _cpp_lookup (pfile, name, len) @@ -121,9 +182,8 @@ _cpp_lookup (pfile, name, len) const U_CHAR *name; int len; { - register const U_CHAR *bp; - register HASHNODE *bucket; - register unsigned int hash; + const U_CHAR *bp; + HASHNODE dummy; if (len < 0) { @@ -131,16 +191,49 @@ _cpp_lookup (pfile, name, len) len = bp - name; } - hash = hashf (name, len) % HASHSIZE; + dummy.name = name; + dummy.length = len; + dummy.hash = -1; + + return (HASHNODE *) htab_find (pfile->hashtab, (void *)&dummy); +} + +/* Find the hashtable slot for name "name". Used to insert or delete. */ +HASHNODE ** +_cpp_lookup_slot (pfile, name, len, insert, hash) + cpp_reader *pfile; + const U_CHAR *name; + int len; + int insert; + unsigned long *hash; +{ + const U_CHAR *bp; + HASHNODE dummy; + HASHNODE **slot; - bucket = pfile->hashtab[hash]; - while (bucket) + if (len < 0) { - if (bucket->length == len && strncmp (bucket->name, name, len) == 0) - return bucket; - bucket = bucket->next; + for (bp = name; is_idchar (*bp); bp++); + len = bp - name; } - return (HASHNODE *) 0; + + dummy.name = name; + dummy.length = len; + dummy.hash = -1; + + slot = (HASHNODE **) htab_find_slot (pfile->hashtab, (void *)&dummy, insert); + if (insert) + *hash = dummy.hash; + return slot; +} + +/* Init the hash table. In here so it can see the hash and eq functions. */ +void +_cpp_init_macro_hash (pfile) + cpp_reader *pfile; +{ + pfile->hashtab = htab_create (HASHSIZE, hash_HASHNODE, + eq_HASHNODE, del_HASHNODE); } /* Free a DEFINITION structure. Used by delete_macro, and by @@ -162,86 +255,6 @@ _cpp_free_definition (d) free (d); } -/* - * Delete a hash node. Some weirdness to free junk from macros. - * More such weirdness will have to be added if you define more hash - * types that need it. - */ - -void -_cpp_delete_macro (hp) - HASHNODE *hp; -{ - if (hp->prev != NULL) - hp->prev->next = hp->next; - if (hp->next != NULL) - hp->next->prev = hp->prev; - - /* make sure that the bucket chain header that - the deleted guy was on points to the right thing afterwards. */ - if (hp == *hp->bucket_hdr) - *hp->bucket_hdr = hp->next; - - if (hp->type == T_MACRO) - _cpp_free_definition (hp->value.defn); - - free (hp); -} - -/* Install a name in the main hash table, even if it is already there. - Name stops with first non alphanumeric, except leading '#'. - Caller must check against redefinition if that is desired. - delete_macro () removes things installed by cpp_install () in fifo order. - this is important because of the `defined' special symbol used - in #if, and also if pushdef/popdef directives are ever implemented. - - If LEN is >= 0, it is the length of the name. - Otherwise, compute the length by scanning the entire name. - - If HASH is >= 0, it is the precomputed hash code. - Otherwise, compute the hash code. */ - -HASHNODE * -_cpp_install (pfile, name, len, type, value) - cpp_reader *pfile; - const U_CHAR *name; - int len; - enum node_type type; - const char *value; -{ - register HASHNODE *hp; - register int i, bucket; - register const U_CHAR *p; - unsigned int hash; - - if (len < 0) - { - p = name; - while (is_idchar(*p)) - p++; - len = p - name; - } - - hash = hashf (name, len) % HASHSIZE; - - i = sizeof (HASHNODE) + len + 1; - hp = (HASHNODE *) xmalloc (i); - bucket = hash; - hp->bucket_hdr = &pfile->hashtab[bucket]; - hp->next = pfile->hashtab[bucket]; - pfile->hashtab[bucket] = hp; - hp->prev = NULL; - if (hp->next != NULL) - hp->next->prev = hp; - hp->type = type; - hp->length = len; - hp->value.cpval = value; - hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE); - memcpy (hp->name, name, len); - hp->name[len] = 0; - return hp; -} - static int macro_cleanup (pbuf, pfile) cpp_buffer *pbuf; @@ -255,7 +268,6 @@ macro_cleanup (pbuf, pfile) return 0; } - /* Read a replacement list for a macro, and build the DEFINITION structure. ARGLIST specifies the formal parameters to look for in the text of the definition. If ARGLIST is null, this is an @@ -503,7 +515,6 @@ collect_expansion (pfile, arglist) while (here > last && is_hspace (pfile->token_buffer [here-1])) here--; CPP_SET_WRITTEN (pfile, here); - CPP_NUL_TERMINATE (pfile); len = CPP_WRITTEN (pfile) - start + 1; /* space for no-concat markers at either end */ @@ -1666,8 +1677,27 @@ _cpp_dump_definition (pfile, sym, len, defn) if (*x == '\r') x += 2, i -= 2; if (i > 0) CPP_PUTS (pfile, x, i); } - if (pfile->lineno == 0) CPP_PUTC (pfile, '\n'); CPP_NUL_TERMINATE (pfile); } + +/* Dump out the hash table. */ +static int +dump_hash_helper (h, p) + void *h; + void *p; +{ + HASHNODE *hp = (HASHNODE *)h; + cpp_reader *pfile = (cpp_reader *)p; + + _cpp_dump_definition (pfile, hp->name, hp->length, hp->value.defn); + return 1; +} + +void +_cpp_dump_macro_hash (pfile) + cpp_reader *pfile; +{ + htab_traverse (pfile->hashtab, dump_hash_helper, pfile); +} |