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!

Repository:
  rL LLVM

http://reviews.llvm.org/D20338

Files:
  include/clang/Basic/FileManager.h
  lib/Basic/FileManager.cpp

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->File.reset();
+  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 @@
 
 public:
   FileEntry()
-      : 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; }


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->File.reset();
+  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 @@
 
 public:
   FileEntry()
-      : 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; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to