[PATCH] D20338: [PCH] Fixed overridden files always invalidating preamble even when unchanged

Cameron via cfe-commits cfe-commits at lists.llvm.org
Tue May 17 14:51:16 PDT 2016

cameron314 created this revision.
cameron314 added a reviewer: rsmith.
cameron314 added a subscriber: cfe-commits.
cameron314 set the repository for this revision to rL LLVM.

Remapped files would always cause the preamble's PCH to be invalidated (even if they hadn't changed) because the file manager was replacing the remapped virtual entry (no modified time) with a real file entry (which has a modified time) when an include directive was processed. This happens when the include directive results in a slightly different path for the same file (e.g. different slash direction, which happens very often on Windows).

Note: This was initially part of D20137 but I had incorrectly applied my own patch, so the `IsVirtual = true` line was in the wrong spot and served no purpose (and was subsequently removed from the patch). Now it actually does something!




Index: lib/Basic/FileManager.cpp
--- lib/Basic/FileManager.cpp
+++ lib/Basic/FileManager.cpp
@@ -301,6 +301,11 @@
     return &UFE;
+  if (UFE.isVirtual()) {
+    UFE.Name = InterndFileName;
+    return &UFE;
+  }
   // Otherwise, we don't have this file yet, add it.
   UFE.Name    = InterndFileName;
   UFE.Size = Data.Size;
@@ -381,6 +386,7 @@
   UFE->Dir     = DirInfo;
   UFE->UID     = NextFileUID++;
+  UFE->IsVirtual = true;
   return UFE;
Index: include/clang/Basic/FileManager.h
--- include/clang/Basic/FileManager.h
+++ include/clang/Basic/FileManager.h
@@ -60,6 +60,7 @@
   bool IsNamedPipe;
   bool InPCH;
   bool IsValid;               // Is this \c FileEntry initialized and valid?
+  bool IsVirtual;             // Is this \c FileEntry a virtual file?
   /// \brief The open file, if it is owned by the \p FileEntry.
   mutable std::unique_ptr<vfs::File> File;
@@ -69,20 +70,23 @@
-      : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false)
+      : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false),
+        IsVirtual(false)
   // FIXME: this is here to allow putting FileEntry in std::map.  Once we have
   // emplace, we shouldn't need a copy constructor anymore.
   /// Intentionally does not copy fields that are not set in an uninitialized
   /// \c FileEntry.
   FileEntry(const FileEntry &FE) : UniqueID(FE.UniqueID),
-      IsNamedPipe(FE.IsNamedPipe), InPCH(FE.InPCH), IsValid(FE.IsValid) {
+      IsNamedPipe(FE.IsNamedPipe), InPCH(FE.InPCH), IsValid(FE.IsValid),
+      IsVirtual(FE.IsVirtual) {
     assert(!isValid() && "Cannot copy an initialized FileEntry");
   const char *getName() const { return Name; }
   bool isValid() const { return IsValid; }
+  bool isVirtual() const { return IsVirtual; }
   off_t getSize() const { return Size; }
   unsigned getUID() const { return UID; }
   const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20338.57523.patch
Type: text/x-patch
Size: 2136 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160517/600eaac9/attachment.bin>

More information about the cfe-commits mailing list