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]

[PATCH] Fix cpp include file handling


Hi!

cpp currently optimizes too much in include file handling.
Specifically, if you have foo.h header in /usr/include and in the local
directory and /usr/include, then
#include <foo.h>
#include "foo.h"

will not include ./foo.h (either it will include /usr/include/foo.h twice or
just once depending on whether it is protected against multiple inclusion).

This patch tries to solve this by remembering where we started searching for
a particular found header. If we are checking if new include is redundant
and it has some search list entries before that point (like with above <>
and ""), we return that we are not sure yet about it and let
find_include_file look through directories until the search list matches
that point.

2000-06-09  Jakub Jelinek  <jakub@redhat.com>

	* cpphash.h (struct ihash): Add search_start.
	* cppfiles.c (make_IHASH): Add search_start argument.
	(redundant_include_p): Return IHASH * to a passed argument,
	let caller know if he has to check some parts of ilist
	before he can use redundant_include_p information.
	If ilist is ABSOLUTE_PATH, don't try to dereference it.
	(find_include_file): If first call to redundant_include_p
	was not sure about the redundancy, use that information
	only if the initial portion of search_start which was not
	searched before does not contain the header.
	(_cpp_fake_ihash, cpp_read_file): Adjust callers of make_HASH
	and redundant_include_p.

--- gcc/cpphash.h.jj	Thu Jun  1 11:56:29 2000
+++ gcc/cpphash.h	Fri Jun  9 19:14:08 2000
@@ -66,6 +66,9 @@ struct ihash
      Used for include_next and to detect redundant includes. */
   struct file_name_list *foundhere;
 
+  /* Search path where we started looking for this file.  */
+  struct file_name_list *search_start;
+
   unsigned int hash;		/* save hash value for future reference */
   const char *nshort;		/* name of file as referenced in #include;
 				   points into name[]  */
--- gcc/cppfiles.c.jj	Fri Jun  2 01:09:18 2000
+++ gcc/cppfiles.c	Fri Jun  9 19:52:34 2000
@@ -43,9 +43,11 @@ Foundation, 59 Temple Place - Suite 330,
 # define O_BINARY 0
 #endif
 
-static IHASH *redundant_include_p PARAMS ((IHASH *, struct file_name_list *));
+static int redundant_include_p PARAMS ((IHASH *, IHASH **,
+					struct file_name_list *));
 static IHASH *make_IHASH	PARAMS ((const char *, const char *,
 					 struct file_name_list *,
+					 struct file_name_list *,
 					 unsigned int, IHASH **));
 static struct file_name_map *read_name_map
 				PARAMS ((cpp_reader *, const char *));
@@ -105,8 +107,12 @@ _cpp_init_include_hash (pfile)
 }
 
 /* Return 0 if the file pointed to by IHASH has never been included before,
-         -1 if it has been included before and need not be again,
-	 or a pointer to an IHASH entry which is the file to be reread.
+          1 if it has been included before, and need not be again,
+          2 if it has been included before and should be included again,
+	  ored with 4 unless we have to check some entries from ilist
+	  before we can be sure.
+   If return value is >= 1, fill RET with a pointer to an IHASH entry
+   which is the file to be reread.
    "Never before" is with respect to the position in ILIST.
 
    This will not detect redundancies involving odd uses of the
@@ -126,29 +132,49 @@ _cpp_init_include_hash (pfile)
    so the test below (i->foundhere == l) may be false even when
    the directories are in fact the same.  */
 
-static IHASH *
-redundant_include_p (ihash, ilist)
+static int
+redundant_include_p (ihash, ret, ilist)
      IHASH *ihash;
+     IHASH **ret;
      struct file_name_list *ilist;
 {
   struct file_name_list *l;
   IHASH *i;
+  int r = 4;
+
+  *ret = NULL;
 
   if (! ihash->foundhere)
     return 0;
 
+  if (ilist && ilist != ihash->search_start && ilist != ABSOLUTE_PATH)
+    {
+      for (l = ilist->next; l; l = l->next)
+	if (l == ihash->search_start)
+	  {
+	    /* We cannot be sure if this include is redundant.  */
+	    r = 0;
+	    break;
+	  }
+    }  
+
   for (i = ihash; i; i = i->next_this_file)
     for (l = ilist; l; l = l->next)
-       if (i->foundhere == l)
-	 /* The cmacro works like this: If it's NULL, the file is to
-	    be included again.  If it's NEVER_REINCLUDE, the file is
-	    never to be included again.  Otherwise it is a macro
-	    hashnode, and the file is to be included again if the
-	    macro is not defined.  */
-	 return (i->cmacro
-		 && (i->cmacro == NEVER_REINCLUDE
-		     || i->cmacro->type != T_VOID))
-	     ? (IHASH *)-1 : i;
+      if (i->foundhere == l)
+	{
+	  /* The cmacro works like this: If it's NULL, the file is to
+	     be included again.  If it's NEVER_REINCLUDE, the file is
+	     never to be included again.  Otherwise it is a macro
+	     hashnode, and the file is to be included again if the
+	     macro is not defined.  */
+	  *ret = i;
+	  return r | ((i->cmacro
+		       && (i->cmacro == NEVER_REINCLUDE
+			   || i->cmacro->type != T_VOID))
+		      ? 1 : 2);
+	}
+      else if (l == ABSOLUTE_PATH)
+	break;
 
   return 0;
 }
@@ -170,9 +196,10 @@ cpp_included (pfile, fname)
 
 /* Create an IHASH entry and insert it in SLOT.  */
 static IHASH *
-make_IHASH (name, fname, path, hash, slot)
+make_IHASH (name, fname, path, search_start, hash, slot)
      const char *name, *fname;
      struct file_name_list *path;
+     struct file_name_list *search_start;
      unsigned int hash;
      IHASH **slot;
 {
@@ -201,6 +228,7 @@ make_IHASH (name, fname, path, hash, slo
     }
   strcpy ((char *)ih->name, name);
   ih->foundhere = path;
+  ih->search_start = search_start;
   ih->cmacro = NULL;
   ih->hash = hash;
   ih->next_this_file = *slot;
@@ -250,9 +278,10 @@ find_include_file (pfile, fname, search_
      int *before;
 {
   struct file_name_list *path;
-  IHASH *ih, **slot;
+  IHASH *ih = NULL, **slot;
   IHASH dummy;
   int f;
+  int redundant = 0;
   char *name;
 
   dummy.nshort = fname;
@@ -262,9 +291,9 @@ find_include_file (pfile, fname, search_
 					      (const void *) &dummy,
 					      dummy.hash, INSERT);
 
-  if (*slot && (ih = redundant_include_p (*slot, path)))
+  if (*slot && ((redundant = redundant_include_p (*slot, &ih, path)) & 4))
     {
-      if (ih == (IHASH *)-1)
+      if (redundant & 1)
 	return -2;
 
       *before = 1;
@@ -304,13 +333,24 @@ find_include_file (pfile, fname, search_
 	  if (f >= 0)
 	    break;
 	  path = path->next;
+	  if (redundant && ih->search_start == path)
+	    {
+	      if (redundant & 1)
+		return -2;
+
+	      *before = 1;
+	      *ihash = ih;
+	      return open_include_file (pfile, ih->name);
+	    }
 	}
       while (path);
     }
   if (f == -1)
     return -1;
 
-  ih = make_IHASH (name, fname, path, dummy.hash, slot);
+  ih = make_IHASH (name, fname, path,
+		   path == ABSOLUTE_PATH ? ABSOLUTE_PATH : search_start,
+		   dummy.hash, slot);
   *before = 0;
   *ihash = ih;
   return f;
@@ -333,7 +373,7 @@ _cpp_fake_ihash (pfile, fname)
 					      dummy.hash, INSERT);
   if (*slot)
     return (*slot)->name;
-  ih = make_IHASH (fname, 0, ABSOLUTE_PATH, dummy.hash, slot);
+  ih = make_IHASH (fname, 0, ABSOLUTE_PATH, ABSOLUTE_PATH, dummy.hash, slot);
   return ih->name;
 }
 
@@ -654,7 +694,7 @@ cpp_read_file (pfile, fname)
 {
   IHASH *ih, **slot;
   IHASH dummy;
-  int f;
+  int f, redundant;
 
   if (fname == NULL)
     fname = "";
@@ -668,13 +708,14 @@ cpp_read_file (pfile, fname)
   slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
 					      (const void *) &dummy,
 					      dummy.hash, INSERT);
-  if (*slot && (ih = redundant_include_p (*slot, ABSOLUTE_PATH)))
+  if (*slot && (redundant = redundant_include_p (*slot, &ih, ABSOLUTE_PATH)))
     {
-      if (ih == (IHASH *) -1)
+      if (redundant & 1)
 	return 1;  /* Already included.  */
     }
   else
-    ih = make_IHASH (fname, 0, ABSOLUTE_PATH, dummy.hash, slot);
+    ih = make_IHASH (fname, 0, ABSOLUTE_PATH, ABSOLUTE_PATH,
+		     dummy.hash, slot);
 
   if (*fname == '\0')
     f = 0;

	Jakub

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