diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-03-06 18:12:47 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-03-06 18:12:47 +0000 |
commit | ed3802e5da6e7d41975b1cb3d7ae3a3b9e855d10 (patch) | |
tree | 71690b8e28318bae5160be0f3b7f2cd765638e61 /lib/Serialization/ASTReader.cpp | |
parent | 36592b1fa381a978b1b6d4b97c66fb274915fe50 (diff) |
[PCH] For HeaderFileInfoTrait, hash the key using size & time of the file.
Previously the hash would be the filename portion of the path, which could be
different for a filename with different case or a symbolic link with a different
name completely.
This did not actually create any issue so far because by validating all headers
in the PCH we created uniqued FileEntries based on inodes, so an #include of
a symbolic link (refering to a file from the PCH) would end up with a FileEntry
with filename same as the one recorded in the PCH.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176566 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 53474f5b0b..d62c42bb1b 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -41,6 +41,7 @@ #include "clang/Serialization/GlobalModuleIndex.h" #include "clang/Serialization/ModuleManager.h" #include "clang/Serialization/SerializationDiagnostic.h" +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/ErrorHandling.h" @@ -1294,24 +1295,28 @@ ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const return LocalID + I->second; } -unsigned HeaderFileInfoTrait::ComputeHash(const char *path) { - return llvm::HashString(llvm::sys::path::filename(path)); +unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) { + return llvm::hash_combine(ikey.Size, ikey.ModTime); } HeaderFileInfoTrait::internal_key_type -HeaderFileInfoTrait::GetInternalKey(const char *path) { return path; } +HeaderFileInfoTrait::GetInternalKey(const FileEntry *FE) { + internal_key_type ikey = { FE->getSize(), FE->getModificationTime(), + FE->getName() }; + return ikey; +} -bool HeaderFileInfoTrait::EqualKey(internal_key_type a, internal_key_type b) { - if (strcmp(a, b) == 0) - return true; - - if (llvm::sys::path::filename(a) != llvm::sys::path::filename(b)) +bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { + if (a.Size != b.Size || a.ModTime != b.ModTime) return false; + if (strcmp(a.Filename, b.Filename) == 0) + return true; + // Determine whether the actual files are equivalent. FileManager &FileMgr = Reader.getFileManager(); - const FileEntry *FEA = FileMgr.getFile(a); - const FileEntry *FEB = FileMgr.getFile(b); + const FileEntry *FEA = FileMgr.getFile(a.Filename); + const FileEntry *FEB = FileMgr.getFile(b.Filename); return (FEA && FEA == FEB); } @@ -1319,11 +1324,20 @@ std::pair<unsigned, unsigned> HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) { unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d); unsigned DataLen = (unsigned) *d++; - return std::make_pair(KeyLen + 1, DataLen); + return std::make_pair(KeyLen, DataLen); } - + +HeaderFileInfoTrait::internal_key_type +HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) { + internal_key_type ikey; + ikey.Size = off_t(clang::io::ReadUnalignedLE64(d)); + ikey.ModTime = time_t(clang::io::ReadUnalignedLE64(d)); + ikey.Filename = (const char *)d; + return ikey; +} + HeaderFileInfoTrait::data_type -HeaderFileInfoTrait::ReadData(const internal_key_type, const unsigned char *d, +HeaderFileInfoTrait::ReadData(internal_key_ref, const unsigned char *d, unsigned DataLen) { const unsigned char *End = d + DataLen; using namespace clang::io; @@ -4109,7 +4123,7 @@ namespace { return false; // Look in the on-disk hash table for an entry for this file name. - HeaderFileInfoLookupTable::iterator Pos = Table->find(This->FE->getName()); + HeaderFileInfoLookupTable::iterator Pos = Table->find(This->FE); if (Pos == Table->end()) return false; |