cppfiles.c (struct _cpp_file): Rename once_only_next to next_file.
authorNeil Booth <neil@daikokuya.co.uk>
Sat, 2 Aug 2003 16:29:46 +0000 (16:29 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Sat, 2 Aug 2003 16:29:46 +0000 (16:29 +0000)
* 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
gcc/cppfiles.c
gcc/cpphash.h
gcc/cpplib.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/import1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/import1.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/import2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/import2.h [new file with mode: 0644]

index e0b7577f90147711fb9ee4e9919b2727103f6074..2c12e4a646a4b6454335c31888b6d100de9542dc 100644 (file)
@@ -1,3 +1,16 @@
+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.
index 2f0ed343b9bef50354939744f2f1dc4e8c71e0d2..007eb09a0b186cc8abdc6b9889c7acbfc35b1680 100644 (file)
@@ -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,
index 951dd2f4101d8ad0ef03aedf5fde1d725008fdaf..8b8f3d896edabeae3267851ce2675540c96d4e8d 100644 (file)
@@ -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,
index 505f48201c3338b7f73c231fe2482700ffd826b0..844a5daec6e12d8c5e67726553b5cae1e0281e64 100644 (file)
@@ -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
index 3bcb80febe8291a1629009ef694ae557e2d182aa..9b982ee16b291c66f58b228d5dcc9662d5e506e5 100644 (file)
@@ -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 (file)
index 0000000..d118d7f
--- /dev/null
@@ -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 (file)
index 0000000..936c525
--- /dev/null
@@ -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 (file)
index 0000000..5c32523
--- /dev/null
@@ -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 (file)
index 0000000..c6a0fa5
--- /dev/null
@@ -0,0 +1,4 @@
+#ifdef BUG
+#error Should not happen!
+#endif
+#define BUG