This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

cpplib: every identifier gets a hash table entry


This patch causes every identifier seen by cpp to get a hashtable
entry, not just active macros.

That might seem like a strange thing to do, but it turns out to be a
considerable simplification for the code that manipulates the
hashtable.  Also, and far more importantly, it will mean that a name
token can be represented by a simple pointer into the hashtable,
rather than having to carry around the text of the name in every token
list.

Also, the name string for a hashnode is now piggybacked on the
hashnode, cutting the number of allocations in half.  This does _not_
use the "struct hack", because the hashtab.h interface can't deal -
possibly to be changed in the future.

zw

	* cpphash.c (_cpp_make_hashnode): Rename make_HASHNODE, now
	static.  Allocate the hashnode and its string in the same
	block of memory.
	(del_HASHNODE): Don't free h->name.
	(_cpp_lookup): If there is no entry for this string, create
	one, of type T_VOID.
	(_cpp_lookup_slot): Delete.
	* cpphash.h: Update prototypes.

	* cpplex.c (maybe_macroexpand): Check for hp->type == T_VOID,
	not hp == NULL.
	* cpplib.c (do_define, do_undef, do_pragma_poison, do_assert,
	do_unassert, cpp_defined): Use _cpp_lookup.  Don't create a
	node here, just fill in the value field properly.  "Delete"
	entries by setting the value field to T_VOID.  Check for
	hp->type == T_VOID, not hp == NULL.

	* Makefile.in (cpplib.o): Don't depend on $(HASHTAB_H).
	* cpperror.c, cppexp.c, cpplex.c, cpplib.c:  Don't include
	hashtab.h.

===================================================================
Index: Makefile.in
--- Makefile.in	2000/04/30 17:30:24	1.431
+++ Makefile.in	2000/05/01 18:08:40
@@ -2064,7 +2064,7 @@ cppulp.o:   cppulp.c   $(CONFIG_H) syste
 cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
 cppexp.o:   cppexp.c   $(CONFIG_H) $(LIBCPP_DEPS)
 cpplex.o:   cpplex.c   $(CONFIG_H) $(LIBCPP_DEPS)
-cpplib.o:   cpplib.c   $(CONFIG_H) $(LIBCPP_DEPS) $(HASHTAB_H)
+cpplib.o:   cpplib.c   $(CONFIG_H) $(LIBCPP_DEPS)
 cpphash.o:  cpphash.c  $(CONFIG_H) $(LIBCPP_DEPS) $(HASHTAB_H)
 cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(HASHTAB_H) mkdeps.h
 
===================================================================
Index: cpperror.c
--- cpperror.c	2000/04/18 20:41:59	1.32
+++ cpperror.c	2000/05/01 18:08:40
@@ -25,7 +25,6 @@ Foundation, 59 Temple Place - Suite 330,
 
 #include "config.h"
 #include "system.h"
-#include "hashtab.h"
 #include "cpplib.h"
 #include "cpphash.h"
 #include "intl.h"
===================================================================
Index: cppexp.c
--- cppexp.c	2000/04/20 19:33:10	1.52
+++ cppexp.c	2000/05/01 18:08:40
@@ -22,7 +22,6 @@ Boston, MA 02111-1307, USA.  */
 #include "config.h"
 #include "system.h"
 #include "cpplib.h"
-#include "hashtab.h"
 #include "cpphash.h"
 
 #ifndef CHAR_TYPE_SIZE
===================================================================
Index: cpphash.c
--- cpphash.c	2000/04/30 17:11:25	1.80
+++ cpphash.c	2000/05/01 18:08:41
@@ -103,6 +103,9 @@ struct funct_defn
 static unsigned int hash_HASHNODE PARAMS ((const void *));
 static int eq_HASHNODE		  PARAMS ((const void *, const void *));
 static void del_HASHNODE	  PARAMS ((void *));
+static HASHNODE *make_HASHNODE	  PARAMS ((const U_CHAR *, size_t,
+					   enum node_type, unsigned int));
+
 static void dump_funlike_macro	  PARAMS ((cpp_reader *,
 					   const struct funct_defn *));
 static int dump_hash_helper	  PARAMS ((void **, void *));
@@ -234,22 +237,21 @@ del_HASHNODE (x)
   HASHNODE *h = (HASHNODE *)x;
 
   _cpp_free_definition (h);
-  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)
+static HASHNODE *
+make_HASHNODE (name, len, type, hash)
      const U_CHAR *name;
      size_t len;
      enum node_type type;
      unsigned int hash;
 {
-  HASHNODE *hp = (HASHNODE *) xmalloc (sizeof (HASHNODE));
-  U_CHAR *p = xmalloc (len + 1);
+  HASHNODE *hp = (HASHNODE *) xmalloc (sizeof (HASHNODE) + len + 1);
+  U_CHAR *p = (U_CHAR *)hp + sizeof (HASHNODE);
 
   hp->type = type;
   hp->length = len;
@@ -271,37 +273,23 @@ _cpp_lookup (pfile, name, len)
      const U_CHAR *name;
      int len;
 {
-  const U_CHAR *bp;
   HASHNODE dummy;
+  HASHNODE *new, **slot;
 
   dummy.name = name;
   dummy.length = len;
   dummy.hash = _cpp_calc_hash (name, len);
-
-  return (HASHNODE *) htab_find_with_hash (pfile->hashtab,
-					   (void *)&dummy, dummy.hash);
-}
-
-/* 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;
-     enum insert_option insert;
-     unsigned int hash;
-{
-  const U_CHAR *bp;
-  HASHNODE dummy;
-
-  dummy.name = name;
-  dummy.length = len;
-  dummy.hash = hash;
 
-  return (HASHNODE **) htab_find_slot_with_hash (pfile->hashtab,
-						 (void *) &dummy,
-						 dummy.hash, insert);
+  slot = (HASHNODE **)
+    htab_find_slot_with_hash (pfile->hashtab, (void *)&dummy,
+			      dummy.hash, INSERT);
+  if (*slot)
+    return *slot;
+
+  new = make_HASHNODE (name, len, T_VOID, dummy.hash);
+  new->value.cpval = NULL;
+  *slot = new;
+  return new;
 }
 
 /* Init the hash table.  In here so it can see the hash and eq functions.  */
===================================================================
Index: cpphash.h
--- cpphash.h	2000/04/30 17:11:25	1.43
+++ cpphash.h	2000/05/01 18:08:42
@@ -210,16 +210,9 @@ extern unsigned char _cpp_IStable[256];
  (CPP_BUFFER(PFILE)->cur - CPP_BUFFER(PFILE)->mark == 1)
 
 /* In cpphash.c */
-extern HASHNODE *_cpp_make_hashnode	PARAMS ((const U_CHAR *, size_t,
-						 enum node_type,
-						 unsigned int));
 extern unsigned int _cpp_calc_hash	PARAMS ((const U_CHAR *, size_t));
 extern HASHNODE *_cpp_lookup		PARAMS ((cpp_reader *,
 						 const U_CHAR *, int));
-extern HASHNODE **_cpp_lookup_slot	PARAMS ((cpp_reader *,
-						 const U_CHAR *, int,
-						 enum insert_option,
-						 unsigned int));
 extern void _cpp_free_definition	PARAMS ((HASHNODE *));
 extern int _cpp_create_definition	PARAMS ((cpp_reader *,
 						 cpp_toklist *, HASHNODE *));
===================================================================
Index: cppinit.c
--- cppinit.c	2000/04/23 17:03:31	1.78
+++ cppinit.c	2000/05/01 18:08:42
@@ -679,10 +679,9 @@ initialize_builtins (pfile)
 	val = b->value;
 
       len = strlen (b->name);
-      hp = _cpp_make_hashnode (b->name, len, b->type,
-			       _cpp_calc_hash (b->name, len));
+      hp = _cpp_lookup (pfile, b->name, len);
       hp->value.cpval = val;
-      *(htab_find_slot (pfile->hashtab, (void *) hp, INSERT)) = hp;
+      hp->type = b->type;
 
       if ((b->flags & DUMP) && CPP_OPTION (pfile, debug_output))
 	dump_special_to_buffer (pfile, b->name);
===================================================================
Index: cpplex.c
--- cpplex.c	2000/04/30 17:30:24	1.31
+++ cpplex.c	2000/05/01 18:08:44
@@ -23,7 +23,6 @@ Foundation, 59 Temple Place - Suite 330,
 #include "config.h"
 #include "system.h"
 #include "intl.h"
-#include "hashtab.h"
 #include "cpplib.h"
 #include "cpphash.h"
 
@@ -1463,7 +1462,8 @@ maybe_macroexpand (pfile, written)
   size_t len = CPP_WRITTEN (pfile) - written;
   HASHNODE *hp = _cpp_lookup (pfile, macro, len);
 
-  if (!hp)
+  /* _cpp_lookup never returns null.  */
+  if (hp->type == T_VOID)
     return 0;
   if (hp->disabled || hp->type == T_IDENTITY)
     {
===================================================================
Index: cpplib.c
--- cpplib.c	2000/04/30 17:11:25	1.159
+++ cpplib.c	2000/05/01 18:08:46
@@ -22,10 +22,8 @@ Foundation, 59 Temple Place - Suite 330,
 #include "config.h"
 #include "system.h"
 
-#include "hashtab.h"
 #include "cpplib.h"
 #include "cpphash.h"
-#include "hashtab.h"
 #include "intl.h"
 #include "symcat.h"
 
@@ -338,8 +336,7 @@ static int
 do_define (pfile)
      cpp_reader *pfile;
 {
-  HASHNODE **slot;
-  unsigned int hash;
+  HASHNODE *node;
   int len;
   U_CHAR *sym;
   cpp_toklist *list = &pfile->directbuf;
@@ -371,27 +368,21 @@ do_define (pfile)
       goto out;
     }
 
-  hash = _cpp_calc_hash (sym, len);
-  slot = _cpp_lookup_slot (pfile, sym, len, INSERT, hash);
-  if (*slot)
-    {
-      /* Check for poisoned identifiers now.  All other checks
-	 are done in cpphash.c.  */
-      if ((*slot)->type == T_POISON)
-	{
-	  cpp_error (pfile, "redefining poisoned `%.*s'", len, sym);
-	  goto out;
-	}
+  node = _cpp_lookup (pfile, sym, len);
+  /* Check for poisoned identifiers now.  All other checks
+     are done in cpphash.c.  */
+  if (node->type == T_POISON)
+    {
+      cpp_error (pfile, "redefining poisoned `%.*s'", len, sym);
+      goto out;
     }
-  else
-    *slot = _cpp_make_hashnode (sym, len, T_VOID, hash);
     
-  if (_cpp_create_definition (pfile, list, *slot) == 0)
+  if (_cpp_create_definition (pfile, list, node) == 0)
     goto out;
 
   if (CPP_OPTION (pfile, debug_output)
       || CPP_OPTION (pfile, dump_macros) == dump_definitions)
-    _cpp_dump_definition (pfile, *slot);
+    _cpp_dump_definition (pfile, node);
   else if (CPP_OPTION (pfile, dump_macros) == dump_names)
     pass_thru_directive (sym, len, pfile, T_DEFINE);
 
@@ -687,8 +678,7 @@ do_undef (pfile)
      cpp_reader *pfile;
 {
   int len;
-  unsigned int hash;
-  HASHNODE **slot;
+  HASHNODE *hp;
   U_CHAR *name;
   long here = CPP_WRITTEN (pfile);
   enum cpp_ttype token;
@@ -715,26 +705,24 @@ do_undef (pfile)
   name = pfile->token_buffer + here;
   CPP_SET_WRITTEN (pfile, here);
 
-  hash = _cpp_calc_hash (name, len);
-  slot = _cpp_lookup_slot (pfile, name, len, NO_INSERT, hash);
-  if (slot)
+  hp = _cpp_lookup (pfile, name, len);
+  if (hp->type == T_VOID)
+    ; /* Not defined in the first place - do nothing.  */
+  else if (hp->type == T_POISON)
+    cpp_error (pfile, "cannot undefine poisoned \"%s\"", hp->name);
+  else
     {
-      HASHNODE *hp = *slot;
-      if (hp->type == T_POISON)
-	cpp_error (pfile, "cannot undefine poisoned `%s'", hp->name);
-      else
-	{
-	  /* If we are generating additional info for debugging (with -g) we
-	     need to pass through all effective #undef commands.  */
-	  if (CPP_OPTION (pfile, debug_output))
-	    pass_thru_directive (hp->name, len, pfile, T_UNDEF);
-
-	  if (hp->type != T_MACRO && hp->type != T_FMACRO
-	      && hp->type != T_EMPTY && hp->type != T_IDENTITY)
-	    cpp_warning (pfile, "undefining `%s'", hp->name);
+      /* If we are generating additional info for debugging (with -g) we
+	 need to pass through all effective #undef commands.  */
+      if (CPP_OPTION (pfile, debug_output))
+	pass_thru_directive (hp->name, len, pfile, T_UNDEF);
+
+      if (hp->type != T_MACRO && hp->type != T_FMACRO
+	  && hp->type != T_EMPTY && hp->type != T_IDENTITY)
+	cpp_warning (pfile, "undefining `%s'", hp->name);
 
-	  htab_clear_slot (pfile->hashtab, (void **)slot);
-	}
+      _cpp_free_definition (hp);
+      hp->type = T_VOID;
     }
 
   return 0;
@@ -947,12 +935,11 @@ do_pragma_poison (pfile)
   /* Poison these symbols so that all subsequent usage produces an
      error message.  */
   U_CHAR *p;
-  HASHNODE **slot;
+  HASHNODE *hp;
   long written;
   size_t len;
   enum cpp_ttype token;
   int writeit;
-  unsigned int hash;
 
   /* As a rule, don't include #pragma poison commands in output,  
      unless the user asks for them.  */
@@ -975,23 +962,15 @@ do_pragma_poison (pfile)
 
       p = pfile->token_buffer + written;
       len = CPP_PWRITTEN (pfile) - p;
-      hash = _cpp_calc_hash (p, len);
-      slot = _cpp_lookup_slot (pfile, p, len, INSERT, hash);
-      if (*slot)
-	{
-	  HASHNODE *hp = *slot;
-	  if (hp->type != T_POISON)
-	    {
-	      cpp_warning (pfile, "poisoning existing macro `%s'", hp->name);
-	      _cpp_free_definition (hp);
-	      hp->type = T_POISON;
-	    }
-	}
+      hp = _cpp_lookup (pfile, p, len);
+      if (hp->type == T_POISON)
+	;  /* It is allowed to poison the same identifier twice.  */
       else
 	{
-	  HASHNODE *hp = _cpp_make_hashnode (p, len, T_POISON, hash);
-	  hp->value.cpval = 0;
-	  *slot = hp;
+	  if (hp->type != T_VOID)
+	    cpp_warning (pfile, "poisoning existing macro `%s'", hp->name);
+	  _cpp_free_definition (hp);
+	  hp->type = T_POISON;
 	}
       if (writeit)
 	CPP_PUTC (pfile, ' ');
@@ -1509,9 +1488,7 @@ do_assert (pfile)
   U_CHAR *sym;
   int ret;
   HASHNODE *base, *this;
-  HASHNODE **bslot, **tslot;
   size_t blen, tlen;
-  unsigned int bhash, thash;
 
   old_written = CPP_WRITTEN (pfile);	/* remember where it starts */
   ret = _cpp_parse_assertion (pfile);
@@ -1529,35 +1506,24 @@ do_assert (pfile)
       cpp_error (pfile, "junk at end of #assert");
       goto error;
     }
-
   sym = pfile->token_buffer + old_written;
-  blen = (U_CHAR *) strchr (sym, '(') - sym;
-  thash = _cpp_calc_hash (sym, tlen);
-  tslot = _cpp_lookup_slot (pfile, sym, tlen, INSERT, thash);
-  if (*tslot)
+
+  this = _cpp_lookup (pfile, sym, tlen);
+  if (this->type == T_ASSERT)
     {
       cpp_warning (pfile, "%s re-asserted", sym);
       goto error;
     }
-
-  bhash = _cpp_calc_hash (sym, blen);
-  bslot = _cpp_lookup_slot (pfile, sym, blen, INSERT, bhash);
-  if (! *bslot)
+      
+  blen = (U_CHAR *) strchr (sym, '(') - sym;
+  base = _cpp_lookup (pfile, sym, blen);
+  if (base->type == T_VOID)
     {
-      *bslot = base = _cpp_make_hashnode (sym, blen, T_ASSERT, bhash);
+      base->type = T_ASSERT;
       base->value.aschain = 0;
     }
-  else
-    {
-      base = *bslot;
-      if (base->type != T_ASSERT)
-	{
-	  /* Token clash - but with what?! */
-	  cpp_ice (pfile, "base->type != T_ASSERT in do_assert");
-	  goto error;
-	}
-    }
-  *tslot = this = _cpp_make_hashnode (sym, tlen, T_ASSERT, thash);
+
+  this->type = T_ASSERT;
   this->value.aschain = base->value.aschain;
   base->value.aschain = this;
 
@@ -1580,13 +1546,13 @@ do_unassert (pfile)
   old_written = CPP_WRITTEN (pfile);
   ret = _cpp_parse_assertion (pfile);
   if (ret == 0)
-    goto error;
+    goto out;
   thislen = CPP_WRITTEN (pfile) - old_written;
 
   if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
     {
       cpp_error (pfile, "junk at end of #unassert");
-      goto error;
+      goto out;
     }
   sym = pfile->token_buffer + old_written;
   CPP_SET_WRITTEN (pfile, old_written);
@@ -1594,40 +1560,43 @@ do_unassert (pfile)
   if (ret == 1)
     {
       base = _cpp_lookup (pfile, sym, thislen);
-      if (! base)
-	goto error;  /* It isn't an error to #undef what isn't #defined,
-			so it isn't an error to #unassert what isn't
-			#asserted either. */
-      
+      if (base->type == T_VOID)
+	goto out;  /* It isn't an error to #undef what isn't #defined,
+		      so it isn't an error to #unassert what isn't
+		      #asserted either. */
+
       for (this = base->value.aschain; this; this = next)
         {
 	  next = this->value.aschain;
-	  htab_remove_elt (pfile->hashtab, this);
+	  this->value.aschain = NULL;
+	  this->type = T_VOID;
 	}
-      htab_remove_elt (pfile->hashtab, base);
+      base->value.aschain = NULL;
+      base->type = T_VOID;
     }
   else
     {
       baselen = (U_CHAR *) strchr (sym, '(') - sym;
       base = _cpp_lookup (pfile, sym, baselen);
-      if (! base) goto error;
+      if (base->type == T_VOID) goto out;
       this = _cpp_lookup (pfile, sym, thislen);
-      if (! this) goto error;
+      if (this->type == T_VOID) goto out;
 
       next = base;
       while (next->value.aschain != this)
 	next = next->value.aschain;
 
       next->value.aschain = this->value.aschain;
-      htab_remove_elt (pfile->hashtab, this);
+      this->value.aschain = NULL;
+      this->type = T_VOID;
 
       if (base->value.aschain == NULL)
 	/* Last answer for this predicate deleted. */
-	htab_remove_elt (pfile->hashtab, base);
+	base->type = T_VOID;
     }
   return 0;
-  
- error:
+
+ out:
   _cpp_skip_rest_of_line (pfile);
   CPP_SET_WRITTEN (pfile, old_written);
   return 0;
@@ -1730,10 +1699,10 @@ cpp_defined (pfile, id, len)
      int len;
 {
   HASHNODE *hp = _cpp_lookup (pfile, id, len);
-  if (hp && hp->type == T_POISON)
+  if (hp->type == T_POISON)
     {
       cpp_error (pfile, "attempt to use poisoned `%s'", hp->name);
       return 0;
     }
-  return (hp != NULL);
+  return (hp->type != T_VOID);
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]