aboutsummaryrefslogtreecommitdiff
path: root/gcc/cppfiles.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cppfiles.c')
-rw-r--r--gcc/cppfiles.c84
1 files changed, 62 insertions, 22 deletions
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 00834aadc4b..b5b5461b9ee 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -154,8 +154,10 @@ struct file_hash_entry
};
static bool open_file (_cpp_file *file);
-static bool pch_open_file (cpp_reader *pfile, _cpp_file *file);
-static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file);
+static bool pch_open_file (cpp_reader *pfile, _cpp_file *file,
+ bool *invalid_pch);
+static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file,
+ bool *invalid_pch);
static bool read_file_guts (cpp_reader *pfile, _cpp_file *file);
static bool read_file (cpp_reader *pfile, _cpp_file *file);
static bool should_stack_file (cpp_reader *, _cpp_file *file, bool import);
@@ -170,7 +172,8 @@ static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp);
static void allocate_file_hash_entries (cpp_reader *pfile);
static struct file_hash_entry *new_file_hash_entry (cpp_reader *pfile);
static int report_missing_guard (void **slot, void *b);
-static int hash_string_eq (const void *p, const void *q);
+static hashval_t file_hash_hash (const void *p);
+static int file_hash_eq (const void *p, const void *q);
static char *read_filename_string (int ch, FILE *f);
static void read_name_map (cpp_dir *dir);
static char *remap_filename (cpp_reader *pfile, _cpp_file *file);
@@ -234,9 +237,13 @@ open_file (_cpp_file *file)
return false;
}
-/* Temporary PCH intercept of opening a file. */
+/* Temporary PCH intercept of opening a file. Try to find a PCH file
+ based on FILE->name and FILE->dir, and test those found for
+ validity using PFILE->cb.valid_pch. Return true iff a valid file is
+ found. Set *INVALID_PCH if a PCH file is found but wasn't valid. */
+
static bool
-pch_open_file (cpp_reader *pfile, _cpp_file *file)
+pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
{
static const char extension[] = ".gch";
const char *path = file->path;
@@ -285,6 +292,7 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file)
closedir (pchdir);
}
file->pch |= valid;
+ *invalid_pch |= ! valid;
}
if (valid)
@@ -297,9 +305,11 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file)
/* Try to open the path FILE->name appended to FILE->dir. This is
where remap and PCH intercept the file lookup process. Return true
- if the file was found, whether or not the open was successful. */
+ if the file was found, whether or not the open was successful.
+ Set *INVALID_PCH to true if a PCH file is found but wasn't valid. */
+
static bool
-find_file_in_dir (cpp_reader *pfile, _cpp_file *file)
+find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
{
char *path;
@@ -309,7 +319,7 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file)
path = append_file_to_dir (file->name, file->dir);
file->path = path;
- if (pch_open_file (pfile, file))
+ if (pch_open_file (pfile, file, invalid_pch))
return true;
if (open_file (file))
@@ -351,13 +361,16 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
{
struct file_hash_entry *entry, **hash_slot;
_cpp_file *file;
+ bool invalid_pch = false;
/* Ensure we get no confusion between cached files and directories. */
if (start_dir == NULL)
- cpp_error (pfile, DL_ICE, "NULL directory in find_file");
+ cpp_error (pfile, CPP_DL_ICE, "NULL directory in find_file");
hash_slot = (struct file_hash_entry **)
- htab_find_slot (pfile->file_hash, fname, INSERT);
+ htab_find_slot_with_hash (pfile->file_hash, fname,
+ htab_hash_string (fname),
+ INSERT);
/* First check the cache before we resort to memory allocation. */
entry = search_cache (*hash_slot, start_dir);
@@ -369,13 +382,21 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
/* Try each path in the include chain. */
for (; !fake ;)
{
- if (find_file_in_dir (pfile, file))
+ if (find_file_in_dir (pfile, file, &invalid_pch))
break;
file->dir = file->dir->next;
if (file->dir == NULL)
{
open_file_failed (pfile, file);
+ if (invalid_pch)
+ {
+ cpp_error (pfile, CPP_DL_ERROR,
+ "one or more PCH files were found, but they were invalid");
+ if (!cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_ERROR,
+ "use -Winvalid-pch for more information");
+ }
break;
}
@@ -432,7 +453,7 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
if (S_ISBLK (file->st.st_mode))
{
- cpp_error (pfile, DL_ERROR, "%s is a block device", file->path);
+ cpp_error (pfile, CPP_DL_ERROR, "%s is a block device", file->path);
return false;
}
@@ -449,7 +470,7 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
does not bite us. */
if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t))
{
- cpp_error (pfile, DL_ERROR, "%s is too large", file->path);
+ cpp_error (pfile, CPP_DL_ERROR, "%s is too large", file->path);
return false;
}
@@ -478,12 +499,13 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
if (count < 0)
{
- cpp_errno (pfile, DL_ERROR, file->path);
+ cpp_errno (pfile, CPP_DL_ERROR, file->path);
return false;
}
if (regular && total != size && STAT_SIZE_RELIABLE (file->st))
- cpp_error (pfile, DL_WARNING, "%s is shorter than expected", file->path);
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s is shorter than expected", file->path);
/* Shrink buffer if we allocated substantially too much. */
if (total + 4096 < size)
@@ -675,7 +697,7 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets,
return make_cpp_dir (pfile, dir_name_of_file (file), pfile->map->sysp);
if (dir == NULL)
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"no include path in which to search for %s", fname);
return dir;
@@ -732,9 +754,9 @@ open_file_failed (cpp_reader *pfile, _cpp_file *file)
/* If we are outputting dependencies but not for this file then
don't error because we can still produce correct output. */
if (CPP_OPTION (pfile, deps.style) && ! print_dep)
- cpp_errno (pfile, DL_WARNING, file->path);
+ cpp_errno (pfile, CPP_DL_WARNING, file->path);
else
- cpp_errno (pfile, DL_ERROR, file->path);
+ cpp_errno (pfile, CPP_DL_ERROR, file->path);
}
}
@@ -778,7 +800,9 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp)
cpp_dir *dir;
hash_slot = (struct file_hash_entry **)
- htab_find_slot (pfile->file_hash, dir_name, INSERT);
+ htab_find_slot_with_hash (pfile->file_hash, dir_name,
+ htab_hash_string (dir_name),
+ INSERT);
/* Have we already hashed this directory? */
for (entry = *hash_slot; entry; entry = entry->next)
@@ -829,7 +853,8 @@ cpp_included (cpp_reader *pfile, const char *fname)
{
struct file_hash_entry *entry;
- entry = htab_find (pfile->file_hash, fname);
+ entry = htab_find_with_hash (pfile->file_hash, fname,
+ htab_hash_string (fname));
while (entry && (entry->start_dir == NULL || entry->u.file->err_no))
entry = entry->next;
@@ -837,9 +862,24 @@ cpp_included (cpp_reader *pfile, const char *fname)
return entry != NULL;
}
+/* Calculate the hash value of a file hash entry P. */
+
+static hashval_t
+file_hash_hash (const void *p)
+{
+ struct file_hash_entry *entry = (struct file_hash_entry *) p;
+ const char *hname;
+ if (entry->start_dir)
+ hname = entry->u.file->name;
+ else
+ hname = entry->u.dir->name;
+
+ return htab_hash_string (hname);
+}
+
/* Compare a string Q against a file hash entry P. */
static int
-hash_string_eq (const void *p, const void *q)
+file_hash_eq (const void *p, const void *q)
{
struct file_hash_entry *entry = (struct file_hash_entry *) p;
const char *fname = (const char *) q;
@@ -857,7 +897,7 @@ hash_string_eq (const void *p, const void *q)
void
_cpp_init_files (cpp_reader *pfile)
{
- pfile->file_hash = htab_create_alloc (127, htab_hash_string, hash_string_eq,
+ pfile->file_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
NULL, xcalloc, free);
allocate_file_hash_entries (pfile);
}