Daily bump.
[gcc.git] / libcpp / files.c
index 7e8877854445d2029bdf40e983af70d050e05610..85c79a1ef9314a0734bfbcc9b4f7e6c05a89cf6b 100644 (file)
@@ -1,5 +1,5 @@
 /* Part of CPP library.  File handling.
-   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
    Written by Per Bothner, 1994.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -50,7 +50,7 @@ along with this program; see the file COPYING3.  If not see
 
 /* This structure represents a file searched for by CPP, whether it
    exists or not.  An instance may be pointed to by more than one
-   file_hash_entry; at present no reference count is kept.  */
+   cpp_file_hash_entry; at present no reference count is kept.  */
 struct _cpp_file
 {
   /* Filename as given to #include or command line switch.  */
@@ -98,19 +98,19 @@ struct _cpp_file
   unsigned short stack_count;
 
   /* If opened with #import or contains #pragma once.  */
-  bool once_only;
+  bool once_only : 1;
 
   /* If read() failed before.  */
-  bool dont_read;
+  bool dont_read : 1;
 
   /* If this file is the main file.  */
-  bool main_file;
+  bool main_file : 1;
 
   /* If BUFFER above contains the true contents of the file.  */
-  bool buffer_valid;
+  bool buffer_valid : 1;
 
   /* If this file is implicitly preincluded.  */
-  bool implicit_preinclude;
+  bool implicit_preinclude : 1;
 };
 
 /* A singly-linked list for all searches for a given file name, with
@@ -140,11 +140,11 @@ struct _cpp_file
    have to do more work re-preprocessing the file, and/or comparing
    its contents against earlier once-only files.
 */
-struct file_hash_entry
+struct cpp_file_hash_entry
 {
-  struct file_hash_entry *next;
+  struct cpp_file_hash_entry *next;
   cpp_dir *start_dir;
-  source_location location;
+  location_t location;
   union
   {
     _cpp_file *file;
@@ -152,10 +152,10 @@ struct file_hash_entry
   } u;
 };
 
-/* Number of entries to put in a file_hash_entry pool.  */
+/* Number of entries to put in a cpp_file_hash_entry pool.  */
 #define FILE_HASH_POOL_SIZE 127
 
-/* A file hash entry pool.  We allocate file_hash_entry object from
+/* A file hash entry pool.  We allocate cpp_file_hash_entry object from
    one of these.  */
 struct file_hash_entry_pool
 {
@@ -164,28 +164,30 @@ struct file_hash_entry_pool
   /* Next pool in the chain; used when freeing.  */
   struct file_hash_entry_pool *next;
   /* The memory pool.  */
-  struct file_hash_entry pool[FILE_HASH_POOL_SIZE];
+  struct cpp_file_hash_entry pool[FILE_HASH_POOL_SIZE];
 };
 
 static bool open_file (_cpp_file *file);
 static bool pch_open_file (cpp_reader *pfile, _cpp_file *file,
                           bool *invalid_pch);
 static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file,
-                             bool *invalid_pch);
-static bool read_file_guts (cpp_reader *pfile, _cpp_file *file);
-static bool read_file (cpp_reader *pfile, _cpp_file *file);
-static bool should_stack_file (cpp_reader *, _cpp_file *file, bool import);
+                             bool *invalid_pch, location_t loc);
+static bool read_file_guts (cpp_reader *pfile, _cpp_file *file,
+                           location_t loc);
+static bool read_file (cpp_reader *pfile, _cpp_file *file,
+                      location_t loc);
 static struct cpp_dir *search_path_head (cpp_reader *, const char *fname,
                                 int angle_brackets, enum include_type);
 static const char *dir_name_of_file (_cpp_file *file);
-static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int);
-static struct file_hash_entry *search_cache (struct file_hash_entry *head,
+static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int,
+                             location_t);
+static struct cpp_file_hash_entry *search_cache (struct cpp_file_hash_entry *head,
                                             const cpp_dir *start_dir);
 static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname);
 static void destroy_cpp_file (_cpp_file *);
 static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp);
 static void allocate_file_hash_entries (cpp_reader *pfile);
-static struct file_hash_entry *new_file_hash_entry (cpp_reader *pfile);
+static struct cpp_file_hash_entry *new_file_hash_entry (cpp_reader *pfile);
 static int report_missing_guard (void **slot, void *b);
 static hashval_t file_hash_hash (const void *p);
 static int file_hash_eq (const void *p, const void *q);
@@ -291,11 +293,13 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
 
   /* If the file is not included as first include from either the toplevel
      file or the command-line it is not a valid use of PCH.  */
-  if (pfile->all_files
-      && pfile->all_files->next_file
-      && !(pfile->all_files->implicit_preinclude
-          || pfile->all_files->next_file->implicit_preinclude))
-    return false;
+  for (_cpp_file *f = pfile->all_files; f; f = f->next_file)
+    if (f->implicit_preinclude)
+      continue;
+    else if (f->main_file)
+      break;
+    else
+      return false;
 
   flen = strlen (path);
   len = flen + sizeof (extension);
@@ -366,10 +370,12 @@ maybe_shorter_path (const char * file)
 /* Try to open the path FILE->name appended to FILE->dir.  This is
    where remap and PCH intercept the file lookup process.  Return true
    if the file was found, whether or not the open was successful.
-   Set *INVALID_PCH to true if a PCH file is found but wasn't valid.  */
+   Set *INVALID_PCH to true if a PCH file is found but wasn't valid.
+   Use LOC when emitting any diagnostics.  */
 
 static bool
-find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
+find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch,
+                 location_t loc)
 {
   char *path;
 
@@ -387,8 +393,14 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
       char *copy;
       void **pp;
 
-      /* We try to canonicalize system headers.  */
-      if (CPP_OPTION (pfile, canonical_system_headers) && file->dir->sysp)
+      /* We try to canonicalize system headers.  For DOS based file
+       * system, we always try to shorten non-system headers, as DOS
+       * has a tighter constraint on max path length.  */
+      if ((CPP_OPTION (pfile, canonical_system_headers) && file->dir->sysp)
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+         || !file->dir->sysp
+#endif
+        )
        {
          char * canonical_path = maybe_shorter_path (path);
          if (canonical_path)
@@ -416,7 +428,7 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
 
       if (file->err_no != ENOENT)
        {
-         open_file_failed (pfile, file, 0);
+         open_file_failed (pfile, file, 0, loc);
          return true;
        }
 
@@ -441,7 +453,7 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
   return false;
 }
 
-/* Return tue iff the missing_header callback found the given HEADER.  */
+/* Return true iff the missing_header callback found the given HEADER.  */
 static bool
 search_path_exhausted (cpp_reader *pfile, const char *header, _cpp_file *file)
 {
@@ -484,17 +496,16 @@ _cpp_find_failed (_cpp_file *file)
    had previously been closed.  To open it again pass the return value
    to open_file().
 
-   If IMPLICIT_PREINCLUDE then it is OK for the file to be missing.
-   If present, it is OK for a precompiled header to be included after
-   it.
-*/
+   If KIND is _cpp_FFK_PRE_INCLUDE then it is OK for the file to be
+   missing.  If present, it is OK for a precompiled header to be
+   included after it.
+
+   Use LOC as the location for any errors.  */
+
 _cpp_file *
 _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
-               bool fake, int angle_brackets, bool implicit_preinclude)
+               int angle_brackets, _cpp_find_file_kind kind, location_t loc)
 {
-  struct file_hash_entry *entry;
-  void **hash_slot;
-  _cpp_file *file;
   bool invalid_pch = false;
   bool saw_bracket_include = false;
   bool saw_quote_include = false;
@@ -502,93 +513,104 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
 
   /* Ensure we get no confusion between cached files and directories.  */
   if (start_dir == NULL)
-    cpp_error (pfile, CPP_DL_ICE, "NULL directory in find_file");
+    cpp_error_at (pfile, CPP_DL_ICE, loc, "NULL directory in find_file");
 
-  hash_slot
+  void **hash_slot
     = htab_find_slot_with_hash (pfile->file_hash, fname,
                                htab_hash_string (fname), INSERT);
 
   /* First check the cache before we resort to memory allocation.  */
-  entry = search_cache ((struct file_hash_entry *) *hash_slot, start_dir);
+  cpp_file_hash_entry *entry
+    = search_cache ((struct cpp_file_hash_entry *) *hash_slot, start_dir);
   if (entry)
     return entry->u.file;
 
-  file = make_cpp_file (pfile, start_dir, fname);
-  file->implicit_preinclude = implicit_preinclude;
-
-  /* Try each path in the include chain.  */
-  for (; !fake ;)
-    {
-      if (find_file_in_dir (pfile, file, &invalid_pch))
-       break;
+  _cpp_file *file = make_cpp_file (pfile, start_dir, fname);
+  file->implicit_preinclude
+    = (kind == _cpp_FFK_PRE_INCLUDE
+       || (pfile->buffer && pfile->buffer->file->implicit_preinclude));
 
-      file->dir = file->dir->next;
-      if (file->dir == NULL)
-       {
-         if (search_path_exhausted (pfile, fname, file))
-           {
-             /* Although this file must not go in the cache, because
-                the file found might depend on things (like the current file)
-                that aren't represented in the cache, it still has to go in
-                the list of all files so that #import works.  */
-             file->next_file = pfile->all_files;
-             pfile->all_files = file;
-             if (*hash_slot == NULL)
-               {
-                 /* If *hash_slot is NULL, the above htab_find_slot_with_hash
-                    call just created the slot, but we aren't going to store
-                    there anything, so need to remove the newly created entry.
-                    htab_clear_slot requires that it is non-NULL, so store
-                    there some non-NULL pointer, htab_clear_slot will
-                    overwrite it immediately.  */
-                 *hash_slot = file;
-                 htab_clear_slot (pfile->file_hash, hash_slot);
-               }
-             return file;
-           }
-
-         if (invalid_pch)
-           {
-             cpp_error (pfile, CPP_DL_ERROR,
-              "one or more PCH files were found, but they were invalid");
-             if (!cpp_get_options (pfile)->warn_invalid_pch)
-               cpp_error (pfile, CPP_DL_ERROR,
-                          "use -Winvalid-pch for more information");
-           }
-         if (implicit_preinclude)
-           {
-             free ((char *) file->name);
-             free (file);
-             if (*hash_slot == NULL)
-               {
-                 /* See comment on the above htab_clear_slot call.  */
-                 *hash_slot = file;
-                 htab_clear_slot (pfile->file_hash, hash_slot);
-               }
-             return NULL;
-           }
-         else
-           open_file_failed (pfile, file, angle_brackets);
+  if (kind != _cpp_FFK_FAKE)
+    /* Try each path in the include chain.  */
+    for (;;)
+      {
+       if (find_file_in_dir (pfile, file, &invalid_pch, loc))
          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)
-       saw_bracket_include = true;
-      else if (file->dir == pfile->quote_include)
-       saw_quote_include = true;
-      else
-       continue;
-
-      entry = search_cache ((struct file_hash_entry *) *hash_slot, file->dir);
-      if (entry)
-       {
-         found_in_cache = file->dir;
-         break;
-       }
-    }
+       file->dir = file->dir->next;
+       if (file->dir == NULL)
+         {
+           if (search_path_exhausted (pfile, fname, file))
+             {
+               /* Although this file must not go in the cache,
+                  because the file found might depend on things (like
+                  the current file) that aren't represented in the
+                  cache, it still has to go in the list of all files
+                  so that #import works.  */
+               file->next_file = pfile->all_files;
+               pfile->all_files = file;
+               if (*hash_slot == NULL)
+                 {
+                   /* If *hash_slot is NULL, the above
+                      htab_find_slot_with_hash call just created the
+                      slot, but we aren't going to store there
+                      anything, so need to remove the newly created
+                      entry.  htab_clear_slot requires that it is
+                      non-NULL, so store there some non-NULL pointer,
+                      htab_clear_slot will overwrite it
+                      immediately.  */
+                   *hash_slot = file;
+                   htab_clear_slot (pfile->file_hash, hash_slot);
+                 }
+               return file;
+             }
+
+           if (invalid_pch)
+             {
+               cpp_error (pfile, CPP_DL_ERROR,
+                          "one or more PCH files were found,"
+                          " but they were invalid");
+               if (!cpp_get_options (pfile)->warn_invalid_pch)
+                 cpp_error (pfile, CPP_DL_ERROR,
+                            "use -Winvalid-pch for more information");
+             }
+
+           if (kind == _cpp_FFK_PRE_INCLUDE)
+             {
+               free ((char *) file->name);
+               free (file);
+               if (*hash_slot == NULL)
+                 {
+                   /* See comment on the above htab_clear_slot call.  */
+                   *hash_slot = file;
+                   htab_clear_slot (pfile->file_hash, hash_slot);
+                 }
+               return NULL;
+             }
+
+           if (kind != _cpp_FFK_HAS_INCLUDE)
+             open_file_failed (pfile, file, angle_brackets, loc);
+           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)
+         saw_bracket_include = true;
+       else if (file->dir == pfile->quote_include)
+         saw_quote_include = true;
+       else
+         continue;
+
+       entry
+         = search_cache ((struct cpp_file_hash_entry *) *hash_slot, file->dir);
+       if (entry)
+         {
+           found_in_cache = file->dir;
+           break;
+         }
+      }
 
   if (entry)
     {
@@ -606,9 +628,9 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
 
   /* Store this new result in the hash table.  */
   entry = new_file_hash_entry (pfile);
-  entry->next = (struct file_hash_entry *) *hash_slot;
+  entry->next = (struct cpp_file_hash_entry *) *hash_slot;
   entry->start_dir = start_dir;
-  entry->location = pfile->line_table->highest_location;
+  entry->location = loc;
   entry->u.file = file;
   *hash_slot = (void *) entry;
 
@@ -619,9 +641,9 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
       && found_in_cache != pfile->bracket_include)
     {
       entry = new_file_hash_entry (pfile);
-      entry->next = (struct file_hash_entry *) *hash_slot;
+      entry->next = (struct cpp_file_hash_entry *) *hash_slot;
       entry->start_dir = pfile->bracket_include;
-      entry->location = pfile->line_table->highest_location;
+      entry->location = loc;
       entry->u.file = file;
       *hash_slot = (void *) entry;
     }
@@ -630,9 +652,9 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
       && found_in_cache != pfile->quote_include)
     {
       entry = new_file_hash_entry (pfile);
-      entry->next = (struct file_hash_entry *) *hash_slot;
+      entry->next = (struct cpp_file_hash_entry *) *hash_slot;
       entry->start_dir = pfile->quote_include;
-      entry->location = pfile->line_table->highest_location;
+      entry->location = loc;
       entry->u.file = file;
       *hash_slot = (void *) entry;
     }
@@ -647,9 +669,11 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
    except for plain files and block devices, since there is no
    reliable portable way of doing this.
 
+   Use LOC for any diagnostics.
+
    FIXME: Flush file cache and try again if we run out of memory.  */
 static bool
-read_file_guts (cpp_reader *pfile, _cpp_file *file)
+read_file_guts (cpp_reader *pfile, _cpp_file *file, location_t loc)
 {
   ssize_t size, total, count;
   uchar *buf;
@@ -657,7 +681,8 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
 
   if (S_ISBLK (file->st.st_mode))
     {
-      cpp_error (pfile, CPP_DL_ERROR, "%s is a block device", file->path);
+      cpp_error_at (pfile, CPP_DL_ERROR, loc,
+                   "%s is a block device", file->path);
       return false;
     }
 
@@ -674,7 +699,8 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
         does not bite us.  */
       if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t))
        {
-         cpp_error (pfile, CPP_DL_ERROR, "%s is too large", file->path);
+         cpp_error_at (pfile, CPP_DL_ERROR, loc,
+                       "%s is too large", file->path);
          return false;
        }
 
@@ -707,13 +733,13 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
 
   if (count < 0)
     {
-      cpp_errno (pfile, CPP_DL_ERROR, file->path);
+      cpp_errno_filename (pfile, CPP_DL_ERROR, file->path, loc);
       free (buf);
       return false;
     }
 
   if (regular && total != size && STAT_SIZE_RELIABLE (file->st))
-    cpp_error (pfile, CPP_DL_WARNING,
+    cpp_error_at (pfile, CPP_DL_WARNING, loc,
               "%s is shorter than expected", file->path);
 
   file->buffer = _cpp_convert_input (pfile,
@@ -728,9 +754,10 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
 
 /* Convenience wrapper around read_file_guts that opens the file if
    necessary and closes the file descriptor after reading.  FILE must
-   have been passed through find_file() at some stage.  */
+   have been passed through find_file() at some stage.  Use LOC for
+   any diagnostics.  */
 static bool
-read_file (cpp_reader *pfile, _cpp_file *file)
+read_file (cpp_reader *pfile, _cpp_file *file, location_t loc)
 {
   /* If we already have its contents in memory, succeed immediately.  */
   if (file->buffer_valid)
@@ -742,27 +769,25 @@ read_file (cpp_reader *pfile, _cpp_file *file)
 
   if (file->fd == -1 && !open_file (file))
     {
-      open_file_failed (pfile, file, 0);
+      open_file_failed (pfile, file, 0, loc);
       return false;
     }
 
-  file->dont_read = !read_file_guts (pfile, file);
+  file->dont_read = !read_file_guts (pfile, file, loc);
   close (file->fd);
   file->fd = -1;
 
   return !file->dont_read;
 }
 
-/* Returns TRUE if FILE's contents have been successfully placed in
-   FILE->buffer and the file should be stacked, otherwise false.  */
+/* Returns TRUE if FILE is already known to be idempotent, and should
+   therefore not be read again.  */
 static bool
-should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
+is_known_idempotent_file (cpp_reader *pfile, _cpp_file *file, bool import)
 {
-  _cpp_file *f;
-
   /* Skip once-only files.  */
   if (file->once_only)
-    return false;
+    return true;
 
   /* We must mark the file once-only if #import now, before header
      guard checks.  Otherwise, undefining the header guard might
@@ -773,13 +798,13 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
 
       /* Don't stack files that have been stacked before.  */
       if (file->stack_count)
-       return false;
+       return true;
     }
 
   /* 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)
-    return false;
+  if (file->cmacro && cpp_macro_p (file->cmacro))
+    return true;
 
   /* Handle PCH files immediately; don't stack them.  */
   if (file->pchname)
@@ -788,12 +813,19 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
       file->fd = -1;
       free ((void *) file->pchname);
       file->pchname = NULL;
-      return false;
+      return true;
     }
 
-  if (!read_file (pfile, file))
-    return false;
+  return false;
+}
+
+/* Return TRUE if file has unique contents, so we should read process
+   it.  The file's contents must already have been read.  */
 
+static bool
+has_unique_contents (cpp_reader *pfile, _cpp_file *file, bool import,
+                    location_t loc)
+{
   /* Check the file against the PCH file.  This is done before
      checking against files we've already seen, since it may save on
      I/O.  */
@@ -814,10 +846,10 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
 
   /* We may have read the file under a different name.  Look
      for likely candidates and compare file contents to be sure.  */
-  for (f = pfile->all_files; f; f = f->next_file)
+  for (_cpp_file *f = pfile->all_files; f; f = f->next_file)
     {
       if (f == file)
-       continue;
+       continue; /* It'sa me!  */
 
       if ((import || f->once_only)
          && f->err_no == 0
@@ -825,7 +857,6 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
          && f->st.st_size == file->st.st_size)
        {
          _cpp_file *ref_file;
-         bool same_file_p = false;
 
          if (f->buffer && !f->buffer_valid)
            {
@@ -838,12 +869,11 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
            /* The file is not stacked anymore.  We can reuse it.  */
            ref_file = f;
 
-         same_file_p = read_file (pfile, ref_file)
-                       /* Size might have changed in read_file().  */
-                       && ref_file->st.st_size == file->st.st_size
-                       && !memcmp (ref_file->buffer,
-                                   file->buffer,
-                                   file->st.st_size);
+         bool same_file_p = (read_file (pfile, ref_file, loc)
+                             /* Size might have changed in read_file().  */
+                             && ref_file->st.st_size == file->st.st_size
+                             && !memcmp (ref_file->buffer, file->buffer,
+                                         file->st.st_size));
 
          if (f->buffer && !f->buffer_valid)
            {
@@ -852,46 +882,51 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
            }
 
          if (same_file_p)
-           break;
+           /* Already seen under a different name.  */
+           return false;
        }
     }
 
-  return f == NULL;
+  return true;
 }
 
 /* Place the file referenced by FILE into a new buffer on the buffer
    stack if possible.  IMPORT is true if this stacking attempt is
    because of a #import directive.  Returns true if a buffer is
-   stacked.  */
+   stacked.  Use LOC for any diagnostics.  */
 bool
-_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
+_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
+                location_t loc)
 {
-  cpp_buffer *buffer;
-  int sysp;
+  if (is_known_idempotent_file (pfile, file, type == IT_IMPORT))
+    return false;
 
-  if (!should_stack_file (pfile, file, import))
-      return false;
+  if (!read_file (pfile, file, loc))
+    return false;
 
-  if (pfile->buffer == NULL || file->dir == NULL)
-    sysp = 0;
-  else
-    sysp = MAX (pfile->buffer->sysp,  file->dir->sysp);
+  if (!has_unique_contents (pfile, file, type == IT_IMPORT, loc))
+    return false;
+
+  int sysp = 0;
+  if (pfile->buffer && file->dir)
+    sysp = MAX (pfile->buffer->sysp, file->dir->sysp);
 
   /* Add the file to the dependencies on its first inclusion.  */
-  if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count)
-    {
-      if (!file->main_file || !CPP_OPTION (pfile, deps.ignore_main_file))
-       deps_add_dep (pfile->deps, file->path);
-    }
+  if (CPP_OPTION (pfile, deps.style) > (sysp != 0)
+      && !file->stack_count
+      && file->path[0]
+      && !(file->main_file && CPP_OPTION (pfile, deps.ignore_main_file)))
+    deps_add_dep (pfile->deps, file->path);
 
   /* Clear buffer_valid since _cpp_clean_line messes it up.  */
   file->buffer_valid = false;
   file->stack_count++;
 
   /* Stack the buffer.  */
-  buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
-                           CPP_OPTION (pfile, preprocessed)
-                           && !CPP_OPTION (pfile, directives_only));
+  cpp_buffer *buffer
+    = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
+                      CPP_OPTION (pfile, preprocessed)
+                      && !CPP_OPTION (pfile, directives_only));
   buffer->file = file;
   buffer->sysp = sysp;
   buffer->to_free = file->buffer_start;
@@ -900,7 +935,18 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
   pfile->mi_valid = true;
   pfile->mi_cmacro = 0;
 
-  /* Generate the call back.  */
+  /* In the case of a normal #include, we're now at the start of the
+     line *following* the #include.  A separate location_t for this
+     location makes no sense, until we do the LC_LEAVE.
+
+     This does not apply if we found a PCH file, we're not a regular
+     include, or we ran out of locations.  */
+  if (file->pchname == NULL
+      && type < IT_DIRECTIVE_HWM
+      && pfile->line_table->highest_location != LINE_MAP_MAX_LOCATION - 1)
+    pfile->line_table->highest_location--;
+
+  /* Add line map and do callbacks.  */
   _cpp_do_file_change (pfile, LC_ENTER, file->path, 1, sysp);
 
   return true;
@@ -979,46 +1025,37 @@ dir_name_of_file (_cpp_file *file)
    Returns true if a buffer was stacked.  */
 bool
 _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
-                   enum include_type type)
-{
-  struct cpp_dir *dir;
-  _cpp_file *file;
-  bool stacked;
-
-  dir = search_path_head (pfile, fname, angle_brackets, type);
+                   enum include_type type, location_t loc)
+{
+  /* For -include command-line flags we have type == IT_CMDLINE.
+     When the first -include file is processed we have the case, where
+     pfile->cur_token == pfile->cur_run->base, we are directly called up
+     by the front end.  However in the case of the second -include file,
+     we are called from _cpp_lex_token -> _cpp_get_fresh_line ->
+     cpp_push_include, with pfile->cur_token != pfile->cur_run->base,
+     and pfile->cur_token[-1].src_loc not (yet) initialized.
+     However, when the include file cannot be found, we need src_loc to
+     be initialized to some safe value: 0 means UNKNOWN_LOCATION.  */
+  if (type == IT_CMDLINE && pfile->cur_token != pfile->cur_run->base)
+    pfile->cur_token[-1].src_loc = 0;
+
+  cpp_dir *dir = search_path_head (pfile, fname, angle_brackets, type);
   if (!dir)
     return false;
 
-  file = _cpp_find_file (pfile, fname, dir, false, angle_brackets,
-                        type == IT_DEFAULT);
+  _cpp_file *file = _cpp_find_file (pfile, fname, dir, angle_brackets,
+                                   type == IT_DEFAULT ? _cpp_FFK_PRE_INCLUDE
+                                   : _cpp_FFK_NORMAL, loc);
   if (type == IT_DEFAULT && file == NULL)
     return false;
 
-  /* Compensate for the increment in linemap_add that occurs if
-      _cpp_stack_file actually stacks the file.  In the case of a
-     normal #include, we're currently at the start of the line
-     *following* the #include.  A separate source_location for this
-     location makes no sense (until we do the LC_LEAVE), and
-     complicates LAST_SOURCE_LINE_LOCATION.  This does not apply if we
-     found a PCH file (in which case linemap_add is not called) or we
-     were included from the command-line.  */
-  if (file->pchname == NULL && file->err_no == 0
-      && type != IT_CMDLINE && type != IT_DEFAULT)
-    pfile->line_table->highest_location--;
-
-  stacked = _cpp_stack_file (pfile, file, type == IT_IMPORT);
-
-  if (!stacked)
-    /* _cpp_stack_file didn't stack the file, so let's rollback the
-       compensation dance we performed above.  */
-    pfile->line_table->highest_location++;
-
-  return stacked;
+  return _cpp_stack_file (pfile, file, type, loc);
 }
 
 /* Could not open FILE.  The complication is dependency output.  */
 static void
-open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets)
+open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets,
+                 location_t loc)
 {
   int sysp = pfile->line_table->highest_line > 1 && pfile->buffer ? pfile->buffer->sysp : 0;
   bool print_dep = CPP_OPTION (pfile, deps.style) > (angle_brackets || !!sysp);
@@ -1030,7 +1067,9 @@ open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets)
       /* If the preprocessor output (other than dependency information) is
          being used, we must also flag an error.  */
       if (CPP_OPTION (pfile, deps.need_preprocessor_output))
-       cpp_errno (pfile, CPP_DL_FATAL, file->path);
+       cpp_errno_filename (pfile, CPP_DL_FATAL,
+                           file->path ? file->path : file->name,
+                           loc);
     }
   else
     {
@@ -1044,16 +1083,20 @@ open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets)
       if (CPP_OPTION (pfile, deps.style) == DEPS_NONE
           || print_dep
           || CPP_OPTION (pfile, deps.need_preprocessor_output))
-       cpp_errno (pfile, CPP_DL_FATAL, file->path);
+       cpp_errno_filename (pfile, CPP_DL_FATAL,
+                           file->path ? file->path : file->name,
+                           loc);
       else
-       cpp_errno (pfile, CPP_DL_WARNING, file->path);
+       cpp_errno_filename (pfile, CPP_DL_WARNING,
+                           file->path ? file->path : file->name,
+                           loc);
     }
 }
 
 /* Search in the chain beginning at HEAD for a file whose search path
    started at START_DIR != NULL.  */
-static struct file_hash_entry *
-search_cache (struct file_hash_entry *head, const cpp_dir *start_dir)
+static struct cpp_file_hash_entry *
+search_cache (struct cpp_file_hash_entry *head, const cpp_dir *start_dir)
 {
   while (head && head->start_dir != start_dir)
     head = head->next;
@@ -1082,6 +1125,7 @@ destroy_cpp_file (_cpp_file *file)
 {
   free ((void *) file->buffer_start);
   free ((void *) file->name);
+  free ((void *) file->path);
   free (file);
 }
 
@@ -1108,10 +1152,10 @@ destroy_all_cpp_files (cpp_reader *pfile)
 static cpp_dir *
 make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp)
 {
-  struct file_hash_entry *entry, **hash_slot;
+  struct cpp_file_hash_entry *entry, **hash_slot;
   cpp_dir *dir;
 
-  hash_slot = (struct file_hash_entry **)
+  hash_slot = (struct cpp_file_hash_entry **)
     htab_find_slot_with_hash (pfile->dir_hash, dir_name,
                              htab_hash_string (dir_name),
                              INSERT);
@@ -1150,7 +1194,7 @@ allocate_file_hash_entries (cpp_reader *pfile)
 }
 
 /* Return a new file hash entry.  */
-static struct file_hash_entry *
+static struct cpp_file_hash_entry *
 new_file_hash_entry (cpp_reader *pfile)
 {
   unsigned int idx;
@@ -1180,9 +1224,9 @@ free_file_hash_entries (cpp_reader *pfile)
 bool
 cpp_included (cpp_reader *pfile, const char *fname)
 {
-  struct file_hash_entry *entry;
+  struct cpp_file_hash_entry *entry;
 
-  entry = (struct file_hash_entry *)
+  entry = (struct cpp_file_hash_entry *)
      htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname));
 
   while (entry && (entry->start_dir == NULL || entry->u.file->err_no))
@@ -1196,12 +1240,14 @@ cpp_included (cpp_reader *pfile, const char *fname)
    filenames aliased by links or redundant . or .. traversals etc.  */
 bool
 cpp_included_before (cpp_reader *pfile, const char *fname,
-                    source_location location)
+                    location_t location)
 {
-  struct file_hash_entry *entry;
+  struct cpp_file_hash_entry *entry
+    = (struct cpp_file_hash_entry *)
+      htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname));
 
-  entry = (struct file_hash_entry *)
-     htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname));
+  if (IS_ADHOC_LOC (location))
+    location = get_location_from_adhoc_loc (pfile->line_table, location);
 
   while (entry && (entry->start_dir == NULL || entry->u.file->err_no
                   || entry->location > location))
@@ -1215,7 +1261,7 @@ cpp_included_before (cpp_reader *pfile, const char *fname,
 static hashval_t
 file_hash_hash (const void *p)
 {
-  struct file_hash_entry *entry = (struct file_hash_entry *) p;
+  struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) p;
   const char *hname;
   if (entry->start_dir)
     hname = entry->u.file->name;
@@ -1229,7 +1275,7 @@ file_hash_hash (const void *p)
 static int
 file_hash_eq (const void *p, const void *q)
 {
-  struct file_hash_entry *entry = (struct file_hash_entry *) p;
+  struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) p;
   const char *fname = (const char *) q;
   const char *hname;
 
@@ -1261,9 +1307,8 @@ _cpp_init_files (cpp_reader *pfile)
   pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string,
                                                    nonexistent_file_hash_eq,
                                                    NULL, xcalloc, free);
-  _obstack_begin (&pfile->nonexistent_file_ob, 0, 0,
-                 (void *(*) (long)) xmalloc,
-                 (void (*) (void *)) free);
+  obstack_specify_allocation (&pfile->nonexistent_file_ob, 0, 0,
+                             xmalloc, free);
 }
 
 /* Finalize everything in this source file.  */
@@ -1293,7 +1338,7 @@ cpp_clear_file_cache (cpp_reader *pfile)
 void
 _cpp_fake_include (cpp_reader *pfile, const char *fname)
 {
-  _cpp_find_file (pfile, fname, pfile->buffer->file->dir, true, 0, false);
+  _cpp_find_file (pfile, fname, pfile->buffer->file->dir, 0, _cpp_FFK_FAKE, 0);
 }
 
 /* Not everyone who wants to set system-header-ness on a buffer can
@@ -1303,14 +1348,15 @@ void
 cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc)
 {
   int flags = 0;
-  const struct line_maps *line_table = pfile->line_table;
-  const struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
+  const class line_maps *line_table = pfile->line_table;
+  const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
   /* 1 = system header, 2 = system header to be treated as C.  */
   if (syshdr)
     flags = 1 + (externc != 0);
   pfile->buffer->sysp = flags;
   _cpp_do_file_change (pfile, LC_RENAME, ORDINARY_MAP_FILE_NAME (map),
-                      SOURCE_LINE (map, pfile->line_table->highest_line), flags);
+                      SOURCE_LINE (map, pfile->line_table->highest_line),
+                      flags);
 }
 
 /* Allow the client to change the current file.  Used by the front end
@@ -1333,7 +1379,7 @@ struct report_missing_guard_data
 static int
 report_missing_guard (void **slot, void *d)
 {
-  struct file_hash_entry *entry = (struct file_hash_entry *) *slot;
+  struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) *slot;
   struct report_missing_guard_data *data
     = (struct report_missing_guard_data *) d;
 
@@ -1411,7 +1457,7 @@ _cpp_compare_file_date (cpp_reader *pfile, const char *fname,
   if (!dir)
     return -1;
 
-  file = _cpp_find_file (pfile, fname, dir, false, angle_brackets, false);
+  file = _cpp_find_file (pfile, fname, dir, angle_brackets, _cpp_FFK_NORMAL, 0);
   if (file->err_no)
     return -1;
 
@@ -1429,7 +1475,7 @@ _cpp_compare_file_date (cpp_reader *pfile, const char *fname,
 bool
 cpp_push_include (cpp_reader *pfile, const char *fname)
 {
-  return _cpp_stack_include (pfile, fname, false, IT_CMDLINE);
+  return _cpp_stack_include (pfile, fname, false, IT_CMDLINE, 0);
 }
 
 /* Pushes the given file, implicitly included at the start of a
@@ -1438,7 +1484,7 @@ cpp_push_include (cpp_reader *pfile, const char *fname)
 bool
 cpp_push_default_include (cpp_reader *pfile, const char *fname)
 {
-  return _cpp_stack_include (pfile, fname, true, IT_DEFAULT);
+  return _cpp_stack_include (pfile, fname, true, IT_DEFAULT, 0);
 }
 
 /* Do appropriate cleanup when a file INC's buffer is popped off the
@@ -1621,7 +1667,7 @@ static char *
 remap_filename (cpp_reader *pfile, _cpp_file *file)
 {
   const char *fname, *p;
-  char *new_dir;
+  char *new_dir, *p3;
   cpp_dir *dir;
   size_t index, len;
 
@@ -1650,9 +1696,15 @@ remap_filename (cpp_reader *pfile, _cpp_file *file)
        return NULL;
 
       len = dir->len + (p - fname + 1);
-      new_dir = XNEWVEC (char, len + 1);
+      new_dir = XNEWVEC (char, len + 2);
+      p3 = new_dir + dir->len;
       memcpy (new_dir, dir->name, dir->len);
-      memcpy (new_dir + dir->len, fname, p - fname + 1);
+      if (dir->len && !IS_DIR_SEPARATOR (dir->name[dir->len - 1]))
+       {
+         *p3++ = '/';
+         len++;
+       }
+      memcpy (p3, fname, p - fname + 1);
       new_dir[len] = '\0';
 
       dir = make_cpp_dir (pfile, new_dir, dir->sysp);
@@ -1823,7 +1875,7 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp)
 
          if (!open_file (f))
            {
-             open_file_failed (pfile, f, 0);
+             open_file_failed (pfile, f, 0, 0);
              free (result);
              return false;
            }
@@ -1939,3 +1991,17 @@ check_file_against_entries (cpp_reader *pfile ATTRIBUTE_UNUSED,
   return bsearch (&d, pchf->entries, pchf->count, sizeof (struct pchf_entry),
                  pchf_compare) != NULL;
 }
+
+/* Return true if the file FNAME is found in the appropriate include file path
+   as indicated by ANGLE_BRACKETS.  */
+
+bool
+_cpp_has_header (cpp_reader *pfile, const char *fname, int angle_brackets,
+                enum include_type type)
+{
+  cpp_dir *start_dir = search_path_head (pfile, fname, angle_brackets, type);
+  _cpp_file *file = _cpp_find_file (pfile, fname, start_dir, angle_brackets,
+                                   _cpp_FFK_HAS_INCLUDE, 0);
+  return file->err_no != ENOENT;
+}
+