cameron314 updated this revision to Diff 57222. cameron314 added a comment.
Updated patch to include later fixes I had made after the initial change. http://reviews.llvm.org/D20137 Files: include/clang/Basic/FileManager.h include/clang/Frontend/ASTUnit.h lib/Basic/FileManager.cpp lib/Frontend/ASTUnit.cpp
Index: lib/Frontend/ASTUnit.cpp =================================================================== --- lib/Frontend/ASTUnit.cpp +++ lib/Frontend/ASTUnit.cpp @@ -1378,7 +1378,7 @@ // First, make a record of those files that have been overridden via // remapping or unsaved_files. - llvm::StringMap<PreambleFileHash> OverriddenFiles; + std::map<llvm::sys::fs::UniqueID, PreambleFileHash> OverriddenFiles; for (const auto &R : PreprocessorOpts.RemappedFiles) { if (AnyFileChanged) break; @@ -1391,40 +1391,47 @@ break; } - OverriddenFiles[R.first] = PreambleFileHash::createForFile( + OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForFile( Status.getSize(), Status.getLastModificationTime().toEpochTime()); } for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) { if (AnyFileChanged) break; - OverriddenFiles[RB.first] = + + vfs::Status Status; + if (FileMgr->getNoncachedStatValue(RB.first, Status)) { + AnyFileChanged = true; + break; + } + + OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForMemoryBuffer(RB.second); } // Check whether anything has changed. - for (llvm::StringMap<PreambleFileHash>::iterator + for (FilesInPreambleMap::iterator F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); !AnyFileChanged && F != FEnd; ++F) { - llvm::StringMap<PreambleFileHash>::iterator Overridden - = OverriddenFiles.find(F->first()); + std::map<llvm::sys::fs::UniqueID, PreambleFileHash>::iterator Overridden + = OverriddenFiles.find(F->first); if (Overridden != OverriddenFiles.end()) { // This file was remapped; check whether the newly-mapped file // matches up with the previous mapping. - if (Overridden->second != F->second) + if (Overridden->second != F->second.second) AnyFileChanged = true; continue; } // The file was not remapped; check whether it has changed on disk. vfs::Status Status; - if (FileMgr->getNoncachedStatValue(F->first(), Status)) { + if (FileMgr->getNoncachedStatValue(F->second.first, Status)) { // If we can't stat the file, assume that something horrible happened. AnyFileChanged = true; - } else if (Status.getSize() != uint64_t(F->second.Size) || + } else if (Status.getSize() != uint64_t(F->second.second.Size) || Status.getLastModificationTime().toEpochTime() != - uint64_t(F->second.ModTime)) + uint64_t(F->second.second.ModTime)) AnyFileChanged = true; } @@ -1612,12 +1619,14 @@ if (!File || File == SourceMgr.getFileEntryForID(SourceMgr.getMainFileID())) continue; if (time_t ModTime = File->getModificationTime()) { - FilesInPreamble[File->getName()] = PreambleFileHash::createForFile( - File->getSize(), ModTime); + FilesInPreamble[File->getUniqueID()] = std::make_pair( + File->getName(), + PreambleFileHash::createForFile(File->getSize(), ModTime)); } else { llvm::MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File); - FilesInPreamble[File->getName()] = - PreambleFileHash::createForMemoryBuffer(Buffer); + FilesInPreamble[File->getUniqueID()] = std::make_pair( + File->getName(), + PreambleFileHash::createForMemoryBuffer(Buffer)); } } 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; @@ -312,6 +317,7 @@ UFE.InPCH = Data.InPCH; UFE.File = std::move(F); UFE.IsValid = true; + UFE.IsVirtual = true; return &UFE; } Index: include/clang/Frontend/ASTUnit.h =================================================================== --- include/clang/Frontend/ASTUnit.h +++ include/clang/Frontend/ASTUnit.h @@ -31,6 +31,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/Support/MD5.h" #include "llvm/Support/Path.h" +#include "llvm/Support/FileSystem.h" #include <cassert> #include <map> #include <memory> @@ -264,12 +265,15 @@ /// a line after skipping the preamble. bool PreambleEndsAtStartOfLine; + typedef std::map<llvm::sys::fs::UniqueID, + std::pair<std::string, PreambleFileHash>> FilesInPreambleMap; + /// \brief Keeps track of the files that were used when computing the /// preamble, with both their buffer size and their modification time. /// /// If any of the files have changed from one compile to the next, /// the preamble must be thrown away. - llvm::StringMap<PreambleFileHash> FilesInPreamble; + FilesInPreambleMap FilesInPreamble; /// \brief When non-NULL, this is the buffer used to store the contents of /// the main file when it has been padded for use with the precompiled 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