aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.co.uk>2003-08-02 16:29:46 +0000
committerNeil Booth <neil@gcc.gnu.org>2003-08-02 16:29:46 +0000
commit49634b3a45f7d9e65a521ac665014d6a81194dc4 (patch)
tree2f3f5d24ede7076f17367de0a1945c6a8e563d8f
parentcf1ee30c6769682cfba0b8518349a451e04d5dcc (diff)
downloadgcc-49634b3a45f7d9e65a521ac665014d6a81194dc4.zip
gcc-49634b3a45f7d9e65a521ac665014d6a81194dc4.tar.gz
gcc-49634b3a45f7d9e65a521ac665014d6a81194dc4.tar.bz2
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
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/cppfiles.c100
-rw-r--r--gcc/cpphash.h11
-rw-r--r--gcc/cpplib.c2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/cpp/import1.c16
-rw-r--r--gcc/testsuite/gcc.dg/cpp/import1.h6
-rw-r--r--gcc/testsuite/gcc.dg/cpp/import2.c11
-rw-r--r--gcc/testsuite/gcc.dg/cpp/import2.h4
9 files changed, 107 insertions, 60 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e0b7577..2c12e4a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,18 @@
2003-08-02 Neil Booth <neil@daikokuya.co.uk>
+ * 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 <neil@daikokuya.co.uk>
+
* cppfiles.c (ENOTDIR): Remove.
(open_file_in_dir): Rename find_file_in_dir. Handle errors
other than ENOENT here.
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 2f0ed34..007eb09 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 951dd2f..8b8f3d8 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 505f4820..844a5da 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 3bcb80f..9b982ee 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2003-08-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * import1.c, import2.c: New tests.
+
2003-08-01 Jakub Jelinek <jakub@redhat.com>
* 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 0000000..d118d7f
--- /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 0000000..936c525
--- /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 0000000..5c32523
--- /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 0000000..c6a0fa5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/import2.h
@@ -0,0 +1,4 @@
+#ifdef BUG
+#error Should not happen!
+#endif
+#define BUG