OSDN Git Service

PR c++/17976
[pf3gnuchains/gcc-fork.git] / libcpp / files.c
index 7d7b271..fc1fa2c 100644 (file)
@@ -415,6 +415,21 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
   /* Try each path in the include chain.  */
   for (; !fake ;)
     {
+      if (file->dir == pfile->quote_include
+         || file->dir == pfile->bracket_include)
+       {
+         entry = search_cache (*hash_slot, file->dir);
+         if (entry)
+           {
+             /* Found the same file again.  Record it as reachable
+                from this position, too.  */
+             free ((char *) file->name);
+             free (file);
+             file = entry->u.file;
+             goto found;
+           }
+       }
+
       if (find_file_in_dir (pfile, file, &invalid_pch))
        break;
 
@@ -435,33 +450,40 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
            }
          break;
        }
-
-      /* Only check the cache for the starting location (done above)
-        and the quote and bracket chain heads because there are no
-        other possible starting points for searches.  */
-      if (file->dir != pfile->bracket_include
-         && file->dir != pfile->quote_include)
-       continue;
-
-      entry = search_cache (*hash_slot, file->dir);
-      if (entry)
-       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;
+
+  /* If this file was found in the directory-of-the-current-file,
+     check whether that directory is reachable via one of the normal
+     search paths.  If so, we must record this entry as being
+     reachable that way, otherwise we will mistakenly reprocess this
+     file if it is included later from the normal search path.  */
+  if (file->dir && start_dir->next == pfile->quote_include)
     {
-      /* This is a new file; put it in the list.  */
-      file->next_file = pfile->all_files;
-      pfile->all_files = file;
+      cpp_dir *d;
+      cpp_dir *proper_start_dir = pfile->quote_include;
+
+      for (d = proper_start_dir;; d = d->next)
+       {
+         if (d == pfile->bracket_include)
+           proper_start_dir = d;
+         if (d == 0)
+           {
+             proper_start_dir = 0;
+             break;
+           }
+         /* file->dir->name will have a trailing slash.  */
+         if (!strncmp (d->name, file->dir->name, file->dir->len - 1))
+           break;
+       }
+      if (proper_start_dir)
+       start_dir = proper_start_dir;
     }
 
+ found:
   /* Store this new result in the hash table.  */
   entry = new_file_hash_entry (pfile);
   entry->next = *hash_slot;
@@ -608,7 +630,7 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
   /* Handle PCH files immediately; don't stack them.  */
   if (file->pch)
     {
-      pfile->cb.read_pch (pfile, file->path, file->fd, file->pchname);
+      pfile->cb.read_pch (pfile, file->pchname, file->fd, file->path);
       close (file->fd);
       file->fd = -1;
       return false;
@@ -823,10 +845,14 @@ open_file_failed (cpp_reader *pfile, _cpp_file *file)
 static struct file_hash_entry *
 search_cache (struct file_hash_entry *head, const cpp_dir *start_dir)
 {
-  while (head && head->start_dir != start_dir)
-    head = head->next;
+  struct file_hash_entry *p;
 
-  return head;
+  /* Look for a file that was found from a search starting at the
+     given location.  */
+  for (p = head; p; p = p->next)
+    if (p->start_dir == start_dir)
+      return p;
+  return 0;
 }
 
 /* Allocate a new _cpp_file structure.  */
@@ -858,7 +884,7 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp)
   cpp_dir *dir;
 
   hash_slot = (struct file_hash_entry **)
-    htab_find_slot_with_hash (pfile->file_hash, dir_name,
+    htab_find_slot_with_hash (pfile->dir_hash, dir_name,
                              htab_hash_string (dir_name),
                              INSERT);
 
@@ -958,6 +984,8 @@ _cpp_init_files (cpp_reader *pfile)
 {
   pfile->file_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
                                        NULL, xcalloc, free);
+  pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
+                                       NULL, xcalloc, free);
   allocate_file_hash_entries (pfile);
 }
 
@@ -966,6 +994,7 @@ void
 _cpp_cleanup_files (cpp_reader *pfile)
 {
   htab_delete (pfile->file_hash);
+  htab_delete (pfile->dir_hash);
 }
 
 /* Enter a file name in the hash for the sake of cpp_included.  */