X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcppfiles.c;h=203619f30b8c89dffe59c6057bbc97ce1153775c;hb=573aba856d39e5b11d72261a6ccb6004dcb923cd;hp=4d8219661d0e92a96e05526adfba4bfaf5441629;hpb=4e844289dc2d6aca17add7956465217079eccdb6;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c index 4d8219661d0..203619f30b8 100644 --- a/gcc/cppfiles.c +++ b/gcc/cppfiles.c @@ -22,6 +22,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" +#include #include "coretypes.h" #include "tm.h" #include "cpplib.h" @@ -87,6 +88,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This structure is used for the table of all includes. */ struct include_file { const char *name; /* actual path name of file */ + const char *header_name; /* the original header found */ const cpp_hashnode *cmacro; /* macro, if any, preventing reinclusion. */ const struct search_path *foundhere; /* location in search path where file was @@ -98,6 +100,13 @@ struct include_file { unsigned short include_count; /* number of times file has been read */ unsigned short refcnt; /* number of stacked buffers using this file */ unsigned char mapped; /* file buffer is mmapped */ + unsigned char pch; /* 0: file not known to be a PCH. + 1: file is a PCH + (on return from find_include_file). + 2: file is not and never will be a valid + precompiled header. + 3: file is always a valid precompiled + header. */ }; /* Variable length record files on VMS will have a stat size that includes @@ -118,6 +127,7 @@ struct include_file { ((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \ || (inc)->cmacro->type == NT_MACRO)) #define NO_INCLUDE_PATH ((struct include_file *) -1) +#define INCLUDE_PCH_P(F) (((F)->pch & 1) != 0) static struct file_name_map *read_name_map PARAMS ((cpp_reader *, const char *)); @@ -130,6 +140,11 @@ static struct include_file * find_include_file PARAMS ((cpp_reader *, const cpp_token *, enum include_type)); static struct include_file *open_file PARAMS ((cpp_reader *, const char *)); +static struct include_file *validate_pch PARAMS ((cpp_reader *, + const char *, + const char *)); +static struct include_file *open_file_pch PARAMS ((cpp_reader *, + const char *)); static int read_include_file PARAMS ((cpp_reader *, struct include_file *)); static bool stack_include_file PARAMS ((cpp_reader *, struct include_file *)); static void purge_cache PARAMS ((struct include_file *)); @@ -212,6 +227,7 @@ find_or_create_entry (pfile, fname) { file = xcnew (struct include_file); file->name = name; + file->header_name = name; file->err_no = errno; node = splay_tree_insert (pfile->all_include_files, (splay_tree_key) file->name, @@ -306,6 +322,89 @@ open_file (pfile, filename) return 0; } +static struct include_file * +validate_pch (pfile, filename, pchname) + cpp_reader *pfile; + const char *filename; + const char *pchname; +{ + struct include_file * file; + + file = open_file (pfile, pchname); + if (file == NULL) + return NULL; + if ((file->pch & 2) == 0) + file->pch = pfile->cb.valid_pch (pfile, pchname, file->fd); + if (INCLUDE_PCH_P (file)) + { + file->header_name = _cpp_simplify_pathname (xstrdup (filename)); + return file; + } + close (file->fd); + file->fd = -1; + return NULL; +} + + +/* Like open_file, but also look for a precompiled header if (a) one exists + and (b) it is valid. */ +static struct include_file * +open_file_pch (pfile, filename) + cpp_reader *pfile; + const char *filename; +{ + if (filename[0] != '\0' + && pfile->cb.valid_pch != NULL) + { + size_t namelen = strlen (filename); + char *pchname = alloca (namelen + 5); + struct include_file * file; + splay_tree_node nd; + + memcpy (pchname, filename, namelen); + memcpy (pchname + namelen, ".pch", 5); + + nd = find_or_create_entry (pfile, pchname); + file = (struct include_file *) nd->value; + + if (file != NULL) + { + if (stat (file->name, &file->st) == 0 && S_ISDIR (file->st.st_mode)) + { + DIR * thedir; + struct dirent *d; + size_t subname_len = namelen + 64; + char *subname = xmalloc (subname_len); + + thedir = opendir (pchname); + if (thedir == NULL) + return NULL; + memcpy (subname, pchname, namelen + 4); + subname[namelen+4] = '/'; + while ((d = readdir (thedir)) != NULL) + { + if (strlen (d->d_name) + namelen + 7 > subname_len) + { + subname_len = strlen (d->d_name) + namelen + 64; + subname = xrealloc (subname, subname_len); + } + strcpy (subname + namelen + 5, d->d_name); + file = validate_pch (pfile, filename, subname); + if (file) + break; + } + closedir (thedir); + free (subname); + } + else + file = validate_pch (pfile, filename, pchname); + if (file) + return file; + } + } + return open_file (pfile, filename); +} + /* Place the file referenced by INC into a new buffer on the buffer stack, unless there are errors, or the file is not re-included because of e.g. multiple-include guards. Returns true if a buffer @@ -332,6 +431,15 @@ stack_include_file (pfile, inc) deps_add_dep (pfile->deps, inc->name); } + /* PCH files get dealt with immediately. */ + if (INCLUDE_PCH_P (inc)) + { + pfile->cb.read_pch (pfile, inc->name, inc->fd, inc->header_name); + close (inc->fd); + inc->fd = -1; + return false; + } + /* Not in cache? */ if (! inc->buffer) { @@ -579,7 +687,7 @@ find_include_file (pfile, header, type) char *name, *n; if (IS_ABSOLUTE_PATHNAME (fname)) - return open_file (pfile, fname); + return open_file_pch (pfile, fname); /* For #include_next, skip in the search path past the dir in which the current file was found, but if it was found via an absolute @@ -615,7 +723,7 @@ find_include_file (pfile, header, type) else n = name; - file = open_file (pfile, n); + file = open_file_pch (pfile, n); if (file) { file->foundhere = path; @@ -757,6 +865,9 @@ _cpp_read_file (pfile, fname) cpp_reader *pfile; const char *fname; { + /* This uses open_file, because we don't allow a PCH to be used as + the toplevel compilation (that would prevent re-compiling an + existing PCH without deleting it first). */ struct include_file *f = open_file (pfile, fname); if (f == NULL)