This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix cpp include file handling
- To: Zack Weinberg <zack at wolery dot cumb dot org>
- Subject: [PATCH] Fix cpp include file handling
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 9 Jun 2000 20:22:38 +0200
- Cc: gcc-patches at gcc dot gnu dot org
- Reply-To: Jakub Jelinek <jakub at redhat dot com>
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