diff options
Diffstat (limited to 'gcc/cppfiles.c')
-rw-r--r-- | gcc/cppfiles.c | 84 |
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); } |