gkeating 03/01/02 13:49:40 Modified: live/gcc3/gcc ChangeLog cppfiles.c cpphash.h cpplib.c cpppch.c dbxout.c ggc.h tree.h live/gcc3/gcc/doc invoke.texi live/gcc3/gcc/testsuite ChangeLog Added: live/gcc3/gcc/testsuite/gcc.dg/pch cpp-1.c cpp-1.h cpp-2.c cpp-2.h Log: Merge from FSF: 2002-12-24 Geoffrey Keating <[EMAIL PROTECTED]> * cpplib.c (count_registered_pragmas): New function. (save_registered_pragmas): New function. (_cpp_save_pragma_names): New function. (restore_registered_pragmas): New function. (_cpp_restore_pragma_names): New function. * cpphash.h (_cpp_save_pragma_names): Prototype. (_cpp_restore_pragma_names): Likewise. * cpppch.c (struct save_macro_item): Split from save_macro_data. (struct save_macro_data): New field 'saved_pragmas'. (save_macros): Update for changes to struct save_macro_data. (cpp_prepare_state): Call _cpp_save_pragma_names, update for changes to struct save_macro_data. (cpp_read_state): Call _cpp_restore_pragma_names, update for changes to struct save_macro_data. * cpppch.c (cpp_read_state): Restore the hashtable references in the cpp_reader. * tree.h (built_in_decls): Mark for PCH. * dbxout.c (lastfile): Don't mark for PCH. * ggc.h: Document PCH calls into memory managers. 2002-12-23 Geoffrey Keating <[EMAIL PROTECTED]> * gcc.dg/pch/cpp-1.h: New. * gcc.dg/pch/cpp-1.c: New. * gcc.dg/pch/cpp-2.h: New. * gcc.dg/pch/cpp-2.c: New. 2002-12-18 Geoffrey Keating <[EMAIL PROTECTED]> * doc/invoke.texi (Precompiled Headers): Document the directory form of PCH. * cppfiles.c (validate_pch): New function. (open_file_pch): Search suitably-named directories for PCH files. Revision Changes Path 1.24 +33 -0 src/live/gcc3/gcc/ChangeLog Index: ChangeLog =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/ChangeLog,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- ChangeLog 2002/12/18 00:31:48 1.23 +++ ChangeLog 2003/01/02 21:49:32 1.24 @@ -1,3 +1,36 @@ +2002-12-24 Geoffrey Keating <[EMAIL PROTECTED]> + + * cpplib.c (count_registered_pragmas): New function. + (save_registered_pragmas): New function. + (_cpp_save_pragma_names): New function. + (restore_registered_pragmas): New function. + (_cpp_restore_pragma_names): New function. + * cpphash.h (_cpp_save_pragma_names): Prototype. + (_cpp_restore_pragma_names): Likewise. + * cpppch.c (struct save_macro_item): Split from save_macro_data. + (struct save_macro_data): New field 'saved_pragmas'. + (save_macros): Update for changes to struct save_macro_data. + (cpp_prepare_state): Call _cpp_save_pragma_names, update + for changes to struct save_macro_data. + (cpp_read_state): Call _cpp_restore_pragma_names, update + for changes to struct save_macro_data. + + * cpppch.c (cpp_read_state): Restore the hashtable references + in the cpp_reader. + + * tree.h (built_in_decls): Mark for PCH. + + * dbxout.c (lastfile): Don't mark for PCH. + + * ggc.h: Document PCH calls into memory managers. + +2002-12-18 Geoffrey Keating <[EMAIL PROTECTED]> + + * doc/invoke.texi (Precompiled Headers): Document the + directory form of PCH. + * cppfiles.c (validate_pch): New function. + (open_file_pch): Search suitably-named directories for PCH files. + 2002-12-11 Geoffrey Keating <[EMAIL PROTECTED]> * gengtype.c (struct write_types_data): Add reorder_note_routine field. 1.58 +63 -8 src/live/gcc3/gcc/cppfiles.c Index: cppfiles.c =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/cppfiles.c,v retrieving revision 1.57 retrieving revision 1.58 diff -u -r1.57 -r1.58 --- cppfiles.c 2002/12/18 00:31:51 1.57 +++ cppfiles.c 2003/01/02 21:49:34 1.58 @@ -22,6 +22,7 @@ #include "config.h" #include "system.h" +#include <dirent.h> #include "cpplib.h" #include "cpphash.h" #include "intl.h" @@ -179,6 +180,9 @@ 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 *)); @@ -395,6 +399,30 @@ 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 * @@ -408,20 +436,47 @@ 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); - file = open_file (pfile, pchname); + + nd = find_or_create_entry (pfile, pchname); + file = (struct include_file *) nd->value; + if (file != NULL) { - if ((file->pch & 2) == 0) - file->pch = pfile->cb.valid_pch (pfile, pchname, file->fd); - file->header_name = xstrdup (filename); - _cpp_simplify_pathname (file->header_name); - if (INCLUDE_PCH_P (file)) + 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; - close (file->fd); - file->fd = -1; } } return open_file (pfile, filename); 1.24 +2 -0 src/live/gcc3/gcc/cpphash.h Index: cpphash.h =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/cpphash.h,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- cpphash.h 2002/12/18 00:31:51 1.23 +++ cpphash.h 2003/01/02 21:49:34 1.24 @@ -554,6 +554,8 @@ extern int _cpp_test_assertion PARAMS ((cpp_reader *, unsigned int *)); extern int _cpp_handle_directive PARAMS ((cpp_reader *, int)); extern void _cpp_define_builtin PARAMS ((cpp_reader *, const char *)); +extern char ** _cpp_save_pragma_names PARAMS ((cpp_reader *)); +extern void _cpp_restore_pragma_names PARAMS ((cpp_reader *, char **)); extern void _cpp_do__Pragma PARAMS ((cpp_reader *)); extern void _cpp_init_directives PARAMS ((cpp_reader *)); extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *)); 1.45 +84 -0 src/live/gcc3/gcc/cpplib.c Index: cpplib.c =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/cpplib.c,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- cpplib.c 2002/12/08 00:37:43 1.44 +++ cpplib.c 2003/01/02 21:49:34 1.45 @@ -133,6 +133,11 @@ static struct pragma_entry *insert_pragma_entry PARAMS ((cpp_reader *, struct pragma_entry **, const cpp_hashnode *, pragma_cb)); +static int count_registered_pragmas PARAMS ((struct pragma_entry *)); +static char ** save_registered_pragmas + PARAMS ((struct pragma_entry *, char **)); +static char ** restore_registered_pragmas + PARAMS ((cpp_reader *, struct pragma_entry *, char **)); static void do_pragma_once PARAMS ((cpp_reader *)); static void do_pragma_poison PARAMS ((cpp_reader *)); static void do_pragma_system_header PARAMS ((cpp_reader *)); @@ -1146,6 +1151,85 @@ cpp_register_pragma (pfile, "GCC", "poison", do_pragma_poison); cpp_register_pragma (pfile, "GCC", "system_header", do_pragma_system_header); cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency); +} + +/* Return the number of registered pragmas in PE. */ + +static int +count_registered_pragmas (pe) + struct pragma_entry *pe; +{ + int ct = 0; + for (; pe != NULL; pe = pe->next) + { + if (pe->is_nspace) + ct += count_registered_pragmas (pe->u.space); + ct++; + } + return ct; +} + +/* Save into SD the names of the registered pragmas referenced by PE, + and return a pointer to the next free space in SD. */ + +static char ** +save_registered_pragmas (pe, sd) + struct pragma_entry *pe; + char **sd; +{ + for (; pe != NULL; pe = pe->next) + { + if (pe->is_nspace) + sd = save_registered_pragmas (pe->u.space, sd); + *sd++ = xmemdup (HT_STR (&pe->pragma->ident), + HT_LEN (&pe->pragma->ident), + HT_LEN (&pe->pragma->ident) + 1); + } + return sd; +} + +/* Return a newly-allocated array which saves the names of the + registered pragmas. */ + +char ** +_cpp_save_pragma_names (pfile) + cpp_reader *pfile; +{ + int ct = count_registered_pragmas (pfile->pragmas); + char **result = xnewvec (char *, ct); + (void) save_registered_pragmas (pfile->pragmas, result); + return result; +} + +/* Restore from SD the names of the registered pragmas referenced by PE, + and return a pointer to the next unused name in SD. */ + +static char ** +restore_registered_pragmas (pfile, pe, sd) + cpp_reader *pfile; + struct pragma_entry *pe; + char **sd; +{ + for (; pe != NULL; pe = pe->next) + { + if (pe->is_nspace) + sd = restore_registered_pragmas (pfile, pe->u.space, sd); + pe->pragma = cpp_lookup (pfile, U *sd, strlen (*sd)); + free (*sd); + sd++; + } + return sd; +} + +/* Restore the names of the registered pragmas from SAVED. */ + +void +_cpp_restore_pragma_names (pfile, saved) + cpp_reader *pfile; + char **saved; +{ + (void) restore_registered_pragmas (pfile, pfile->pragmas, saved); + free (saved); } /* Pragmata handling. We handle some, and pass the rest on to the 1.2 +50 -23 src/live/gcc3/gcc/cpppch.c Index: cpppch.c =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/cpppch.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- cpppch.c 2002/12/18 00:31:52 1.1 +++ cpppch.c 2003/01/02 21:49:34 1.2 @@ -480,12 +480,20 @@ This code assumes that there might be hundreds, but not thousands of existing definitions. */ -struct save_macro_data { - struct save_macro_data *next; - size_t count; +struct save_macro_item { + struct save_macro_item *next; struct cpp_hashnode macs[64]; }; +struct save_macro_data +{ + struct save_macro_item *macros; + size_t count; + char **saved_pragmas; +}; + +/* Save the definition of a single macro, so that it will persist across + a PCH restore. */ static int save_macros (r, h, data_p) @@ -493,20 +501,20 @@ cpp_hashnode *h; void *data_p; { - struct save_macro_data **data = (struct save_macro_data **)data_p; + struct save_macro_data *data = (struct save_macro_data *)data_p; if (h->type != NT_VOID && (h->flags & NODE_BUILTIN) == 0) { cpp_hashnode *save; - if ((*data)->count == ARRAY_SIZE ((*data)->macs)) + if (data->count == ARRAY_SIZE (data->macros->macs)) { - struct save_macro_data *d = *data; - *data = xmalloc (sizeof (struct save_macro_data)); - (*data)->next = d; - (*data)->count = 0; + struct save_macro_item *d = data->macros; + data->macros = xmalloc (sizeof (struct save_macro_item)); + data->macros->next = d; + data->count = 0; } - save = (*data)->macs + (*data)->count; - (*data)->count++; + save = data->macros->macs + data->count; + data->count++; memcpy (save, h, sizeof (struct cpp_hashnode)); HT_STR (&save->ident) = xmemdup (HT_STR (HT_NODE (save)), HT_LEN (HT_NODE (save)), @@ -515,6 +523,9 @@ return 1; } +/* Prepare to restore the state, by saving the currently-defined + macros in 'data'. */ + void cpp_prepare_state (r, data) cpp_reader *r; @@ -522,13 +533,13 @@ { struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data)); - d->next = NULL; - d->count = 0; - cpp_forall_identifiers (r, save_macros, &d); + d->macros = NULL; + d->count = ARRAY_SIZE (d->macros->macs); + cpp_forall_identifiers (r, save_macros, d); + d->saved_pragmas = _cpp_save_pragma_names (r); *data = d; } - /* Erase all the existing macros and assertions. */ static int @@ -561,21 +572,32 @@ size_t defnlen = 256; unsigned char *defn = xmalloc (defnlen); struct lexer_state old_state; - struct save_macro_data *d; - size_t i; + struct save_macro_item *d; + size_t i, mac_count; int saved_line = r->line; - /* First, erase all the existing hashtable entries for macros. At - this point, they're all from the PCH file, and their pointers - won't be valid. */ + /* Erase all the existing hashtable entries for macros. At this + point, they're all from the PCH file, and their pointers won't be + valid. */ cpp_forall_identifiers (r, reset_ht, NULL); + /* Restore spec_nodes, which will be full of references to the old + hashtable entries and so will now be invalid. */ + { + struct spec_nodes *s = &r->spec_nodes; + s->n_defined = cpp_lookup (r, DSC("defined")); + s->n_true = cpp_lookup (r, DSC("true")); + s->n_false = cpp_lookup (r, DSC("false")); + s->n__VA_ARGS__ = cpp_lookup (r, DSC("__VA_ARGS__")); + } + /* Run through the carefully-saved macros, insert them. */ - d = data; + d = data->macros; + mac_count = data->count; while (d) { - struct save_macro_data *nextd; - for (i = 0; i < d->count; i++) + struct save_macro_item *nextd; + for (i = 0; i < mac_count; i++) { cpp_hashnode *h; @@ -589,7 +611,12 @@ nextd = d->next; free (d); d = nextd; + mac_count = ARRAY_SIZE (d->macs); } + + _cpp_restore_pragma_names (r, data->saved_pragmas); + + free (data); old_state = r->state; 1.39 +1 -1 src/live/gcc3/gcc/dbxout.c Index: dbxout.c =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/dbxout.c,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- dbxout.c 2002/12/18 00:31:52 1.38 +++ dbxout.c 2003/01/02 21:49:34 1.39 @@ -344,7 +344,7 @@ /* Last source file name mentioned in a NOTE insn. */ -static GTY(()) const char *lastfile; +static const char *lastfile; /* Current working directory. */ 1.14 +26 -3 src/live/gcc3/gcc/ggc.h Index: ggc.h =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/ggc.h,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- ggc.h 2002/12/18 00:31:56 1.13 +++ ggc.h 2003/01/02 21:49:34 1.14 @@ -133,12 +133,14 @@ extern void gt_pch_n_S PARAMS ((const void *)); extern void gt_ggc_m_S PARAMS ((void *)); +/* Initialise the string pool. */ +extern void init_stringpool PARAMS ((void)); -/* A GC implementation must provide these functions. */ +/* A GC implementation must provide these functions. They are internal + to the GC system. */ /* Initialize the garbage collector. */ extern void init_ggc PARAMS ((void)); -extern void init_stringpool PARAMS ((void)); /* Start a new GGC context. Memory allocated in previous contexts will not be collected while the new context is active. */ @@ -150,23 +152,44 @@ struct ggc_pch_data; +/* Return a new ggc_pch_data structure. */ extern struct ggc_pch_data *init_ggc_pch PARAMS ((void)); + +/* The second parameter and third parameters give the address and size + of an object. Update the ggc_pch_data structure with as much of + that information as is necessary. */ extern void ggc_pch_count_object PARAMS ((struct ggc_pch_data *, void *, size_t)); + +/* Return the total size of the data to be written to hold all + the objects previously passed to ggc_pch_count_object. */ extern size_t ggc_pch_total_size PARAMS ((struct ggc_pch_data *)); + +/* The objects, when read, will most likely be at the address + in the second parameter. */ extern void ggc_pch_this_base PARAMS ((struct ggc_pch_data *, void *)); + +/* Assuming that the objects really do end up at the address + passed to ggc_pch_this_base, return the address of this object. */ extern char *ggc_pch_alloc_object PARAMS ((struct ggc_pch_data *, void *, size_t)); + +/* Write out any initial information required. */ extern void ggc_pch_prepare_write PARAMS ((struct ggc_pch_data *, FILE *)); +/* Write out this object, including any padding. */ extern void ggc_pch_write_object PARAMS ((struct ggc_pch_data *, FILE *, void *, void *, size_t)); +/* All objects have been written, write out any final information + required. */ extern void ggc_pch_finish PARAMS ((struct ggc_pch_data *, FILE *)); -extern void ggc_pch_read PARAMS ((FILE *, void *)); +/* A PCH file has just been read in at the address specified second + parameter. Set up the GC implementation for the new objects. */ +extern void ggc_pch_read PARAMS ((FILE *, void *)); /* Allocation. */ 1.63 +1 -1 src/live/gcc3/gcc/tree.h Index: tree.h =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/tree.h,v retrieving revision 1.62 retrieving revision 1.63 diff -u -r1.62 -r1.63 --- tree.h 2002/12/18 00:31:57 1.62 +++ tree.h 2003/01/02 21:49:34 1.63 @@ -98,7 +98,7 @@ extern const char *const built_in_names[(int) END_BUILTINS]; /* An array of _DECL trees for the above. */ -extern tree built_in_decls[(int) END_BUILTINS]; +extern GTY(()) tree built_in_decls[(int) END_BUILTINS]; /* The definition of tree nodes fills the next several pages. */ 1.47 +9 -0 src/live/gcc3/gcc/doc/invoke.texi Index: invoke.texi =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/doc/invoke.texi,v retrieving revision 1.46 retrieving revision 1.47 diff -u -r1.46 -r1.47 --- invoke.texi 2002/12/18 00:32:20 1.46 +++ invoke.texi 2003/01/02 21:49:37 1.47 @@ -11104,6 +11104,15 @@ have guards against multiple inclusion, they will be skipped because they've already been included (in the precompiled header). +If you need to precompile the same header file for different +languages, targets, or compiler options, you can instead make a +@emph{directory} named like @file{all.h.pch}, and put each precompiled +header in the directory. (It doesn't matter what you call the files +in the directory, every precompiled header in the directory will be +considered.) The first precompiled header encountered in the +directory that is valid for this compilation will be used; they're +searched in no particular order. + There are many other possibilities, limited only by your imagination, good sense, and the constraints of your build system. 1.23 +7 -0 src/live/gcc3/gcc/testsuite/ChangeLog Index: ChangeLog =================================================================== RCS file: /cvs/Darwin/src/live/gcc3/gcc/testsuite/ChangeLog,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- ChangeLog 2002/12/18 00:32:29 1.22 +++ ChangeLog 2003/01/02 21:49:38 1.23 @@ -1,3 +1,10 @@ +2002-12-23 Geoffrey Keating <[EMAIL PROTECTED]> + + * gcc.dg/pch/cpp-1.h: New. + * gcc.dg/pch/cpp-1.c: New. + * gcc.dg/pch/cpp-2.h: New. + * gcc.dg/pch/cpp-2.c: New. + 2002-11-19 Geoffrey Keating <[EMAIL PROTECTED]> * gcc.dg/pch/except-1.h: New. 1.1 src/live/gcc3/gcc/testsuite/gcc.dg/pch/cpp-1.c Index: cpp-1.c =================================================================== #include "cpp-1.hp" #if !defined(__GNUC__) panic! panic! #endif 1.1 src/live/gcc3/gcc/testsuite/gcc.dg/pch/cpp-1.h Index: cpp-1.h =================================================================== /* Empty. */ 1.1 src/live/gcc3/gcc/testsuite/gcc.dg/pch/cpp-2.c Index: cpp-2.c =================================================================== /* { dg-options "-Wunknown-pragmas -I." } */ #include "cpp-2.hp" #pragma GCC poison not_used 1.1 src/live/gcc3/gcc/testsuite/gcc.dg/pch/cpp-2.h Index: cpp-2.h =================================================================== /* Empty. */