From 49634b3a45f7d9e65a521ac665014d6a81194dc4 Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Sat, 2 Aug 2003 16:29:46 +0000 Subject: [PATCH] cppfiles.c (struct _cpp_file): Rename once_only_next to next_file. * cppfiles.c (struct _cpp_file): Rename once_only_next to next_file. Remove import and pragma_once, add once_only. (find_file): Add new file structures to the all_files list. (should_stack_file): Mark #import-ed files once-only, and don't stack them if the file has already been stacked. (_cp_mark_file_once_only): Simplify. * cpphash.h (struct cpp_reader): Rename once_only_files to all_files. Rename saw_pragma_once to seen_once_only. (_cpp_mark_file_once_only): Update prototype. * cpplib.c (do_pragma_once): Update. testsuite: * import1.c, import2.c: New tests. From-SVN: r70106 --- gcc/ChangeLog | 13 ++++ gcc/cppfiles.c | 100 +++++++++++++---------------- gcc/cpphash.h | 11 ++-- gcc/cpplib.c | 2 +- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/cpp/import1.c | 16 +++++ gcc/testsuite/gcc.dg/cpp/import1.h | 6 ++ gcc/testsuite/gcc.dg/cpp/import2.c | 11 ++++ gcc/testsuite/gcc.dg/cpp/import2.h | 4 ++ 9 files changed, 107 insertions(+), 60 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/import1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/import1.h create mode 100644 gcc/testsuite/gcc.dg/cpp/import2.c create mode 100644 gcc/testsuite/gcc.dg/cpp/import2.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e0b7577f901..2c12e4a646a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2003-08-02 Neil Booth + + * cppfiles.c (struct _cpp_file): Rename once_only_next to + next_file. Remove import and pragma_once, add once_only. + (find_file): Add new file structures to the all_files list. + (should_stack_file): Mark #import-ed files once-only, and + don't stack them if the file has already been stacked. + (_cp_mark_file_once_only): Simplify. + * cpphash.h (struct cpp_reader): Rename once_only_files + to all_files. Rename saw_pragma_once to seen_once_only. + (_cpp_mark_file_once_only): Update prototype. + * cpplib.c (do_pragma_once): Update. + 2003-08-02 Neil Booth * cppfiles.c (ENOTDIR): Remove. diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c index 2f0ed343b9b..007eb09a0b1 100644 --- a/gcc/cppfiles.c +++ b/gcc/cppfiles.c @@ -70,8 +70,8 @@ struct _cpp_file been calculated yet. */ const char *dir_name; - /* Chain through #import-ed files or those containing #pragma once. */ - struct _cpp_file *once_only_next; + /* Chain through all files. */ + struct _cpp_file *next_file; /* The contents of NAME after calling read_file(). */ const uchar *buffer; @@ -97,11 +97,8 @@ struct _cpp_file /* Number of times the file has been stacked for preprocessing. */ unsigned short stack_count; - /* If opened with #import. */ - bool import; - - /* If contains #pragma once. */ - bool pragma_once; + /* If opened with #import or contains #pragma once. */ + bool once_only; /* If read() failed before. */ bool dont_read; @@ -383,13 +380,21 @@ find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool fake) entry = search_cache (*hash_slot, file->dir); if (entry) - { - /* Cache for START_DIR too, sharing the _cpp_file structure. */ - free ((char *) file->name); - free (file); - file = entry->u.file; - break; - } + break; + } + + if (entry) + { + /* Cache for START_DIR too, sharing the _cpp_file structure. */ + free ((char *) file->name); + free (file); + file = entry->u.file; + } + else + { + /* This is a new file; put it in the list. */ + file->next_file = pfile->all_files; + pfile->all_files = file; } /* Store this new result in the hash table. */ @@ -520,6 +525,22 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) { _cpp_file *f; + /* Skip once-only files. */ + if (file->once_only) + return false; + + /* We must mark the file once-only if #import now, before header + guard checks. Otherwise, undefining the header guard might + cause the file to be re-stacked. */ + if (import) + { + _cpp_mark_file_once_only (pfile, file); + + /* Don't stack files that have been stacked before. */ + if (file->stack_count) + return false; + } + /* Skip if the file had a header guard and the macro is defined. PCH relies on this appearing before the PCH handler below. */ if (file->cmacro && file->cmacro->type == NT_MACRO) @@ -534,34 +555,23 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) return false; } - /* Did this file contain #pragma once? */ - if (file->pragma_once) - return false; - - /* Are we #import-ing a previously #import-ed file? */ - if (import && file->import) - return false; - - /* Read the file's contents. */ if (!read_file (pfile, file)) return false; - /* Nothing to check if this isn't #import and there haven't been any - #pragma_once directives. */ - if (!import && !pfile->saw_pragma_once) + /* Now we've read the file's contents, we can stack it if there + are no once-only files. */ + if (!pfile->seen_once_only) return true; - /* We may have #imported it under a different name, though. Look + /* We may have read the file under a different name. Look for likely candidates and compare file contents to be sure. */ - for (f = pfile->once_only_files; f; f = f->once_only_next) + for (f = pfile->all_files; f; f = f->next_file) { if (f == file) continue; - if (!f->pragma_once && !(f->import && import)) - continue; - - if (f->err_no == 0 + if ((import || f->once_only) + && f->err_no == 0 && f->st.st_mtime == file->st.st_mtime && f->st.st_size == file->st.st_size && read_file (pfile, f) @@ -571,9 +581,6 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) break; } - if (import || f != NULL) - _cpp_mark_file_once_only (pfile, file, import); - return f == NULL; } @@ -619,27 +626,12 @@ stack_file (cpp_reader *pfile, _cpp_file *file, bool import) return true; } -/* Mark FILE to be included once only. IMPORT is true if because of - #import, otherwise it is assumed to be #pragma once. */ +/* Mark FILE to be included once only. */ void -_cpp_mark_file_once_only (cpp_reader *pfile, _cpp_file *file, bool import) +_cpp_mark_file_once_only (cpp_reader *pfile, _cpp_file *file) { - /* Put it on the once-only list if it's not on there already (an - earlier #include with a #pragma once might have put it on there - already). */ - if (!file->import && !file->pragma_once) - { - file->once_only_next = pfile->once_only_files; - pfile->once_only_files = file; - } - - if (import) - file->import = true; - else - { - pfile->saw_pragma_once = true; - file->pragma_once = true; - } + pfile->seen_once_only = true; + file->once_only = true; } /* Return the directory from which searching for FNAME should start, diff --git a/gcc/cpphash.h b/gcc/cpphash.h index 951dd2f4101..8b8f3d896ed 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -359,8 +359,8 @@ struct cpp_reader struct cpp_dir *bracket_include; /* <> */ struct cpp_dir no_search_path; /* No path. */ - /* Chain of files that were #import-ed or contain #pragma once. */ - struct _cpp_file *once_only_files; + /* Chain of all hashed _cpp_file instances. */ + struct _cpp_file *all_files; /* File and directory hash table. */ struct htab *file_hash; @@ -371,8 +371,9 @@ struct cpp_reader directory. */ bool quote_ignores_source_dir; - /* Non-zero if any file has contained #pragma once. */ - bool saw_pragma_once; + /* Non-zero if any file has contained #pragma once or #import has + been used. */ + bool seen_once_only; /* Multiple include optimization. */ const cpp_hashnode *mi_cmacro; @@ -514,7 +515,7 @@ extern void _cpp_init_hashtable (cpp_reader *, hash_table *); extern void _cpp_destroy_hashtable (cpp_reader *); /* In cppfiles.c */ -extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *, bool); +extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *); extern void _cpp_fake_include (cpp_reader *, const char *); extern bool _cpp_stack_file (cpp_reader *, const char *); extern bool _cpp_stack_include (cpp_reader *, const char *, int, diff --git a/gcc/cpplib.c b/gcc/cpplib.c index 505f48201c3..844a5daec6e 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -1167,7 +1167,7 @@ do_pragma_once (cpp_reader *pfile) cpp_error (pfile, DL_WARNING, "#pragma once in main file"); check_eol (pfile); - _cpp_mark_file_once_only (pfile, pfile->buffer->file, false); + _cpp_mark_file_once_only (pfile, pfile->buffer->file); } /* Handle #pragma GCC poison, to poison one or more identifiers so diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3bcb80febe8..9b982ee16b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-08-02 Neil Booth + + * import1.c, import2.c: New tests. + 2003-08-01 Jakub Jelinek * g++.dg/eh/crossjump1.C: New test. diff --git a/gcc/testsuite/gcc.dg/cpp/import1.c b/gcc/testsuite/gcc.dg/cpp/import1.c new file mode 100644 index 00000000000..d118d7fb051 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/import1.c @@ -0,0 +1,16 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. */ + +/* { dg-do preprocess } */ +/* { dg-options "" } */ + +/* This tests that our eagerness to apply the multiple include guard + optimization to the #import doesn't stop us marking the file + once-only. + + Neil Booth, 2 August 2003. */ + +#include "import1.h" +#import "import1.h" +#undef IMPORT1_H +#define BUG +#include "import1.h" diff --git a/gcc/testsuite/gcc.dg/cpp/import1.h b/gcc/testsuite/gcc.dg/cpp/import1.h new file mode 100644 index 00000000000..936c525eb7f --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/import1.h @@ -0,0 +1,6 @@ +#ifndef IMPORT1_H +#define IMPORT1_H +#ifdef BUG +#error Should not happen +#endif +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/import2.c b/gcc/testsuite/gcc.dg/cpp/import2.c new file mode 100644 index 00000000000..5c32523880e --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/import2.c @@ -0,0 +1,11 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. */ + +/* { dg-do preprocess } */ +/* { dg-options "" } */ + +/* This tests that the file is only included once + Neil Booth, 2 August 2003. */ + +#include "import2.h" +#import "import2.h" +#include "import2.h" diff --git a/gcc/testsuite/gcc.dg/cpp/import2.h b/gcc/testsuite/gcc.dg/cpp/import2.h new file mode 100644 index 00000000000..c6a0fa5978a --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/import2.h @@ -0,0 +1,4 @@ +#ifdef BUG +#error Should not happen! +#endif +#define BUG -- 2.30.2