aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-06 18:12:47 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-06 18:12:47 +0000
commited3802e5da6e7d41975b1cb3d7ae3a3b9e855d10 (patch)
tree71690b8e28318bae5160be0f3b7f2cd765638e61 /lib/Serialization/ASTReader.cpp
parent36592b1fa381a978b1b6d4b97c66fb274915fe50 (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.cpp42
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;