From 2d52be56ff595341be3c6cec337af6763804ce66 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sun, 21 Mar 2010 22:49:54 +0000 Subject: [PATCH] Keep track of the size/modification time of each file source-location entry in a precompiled header, so that we can detect modified files even when we miss in the stat cache. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99149 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticFrontendKinds.td | 3 +++ lib/Basic/SourceManager.cpp | 3 +-- lib/Frontend/PCHReader.cpp | 17 ++++++++++++----- lib/Frontend/PCHWriter.cpp | 7 +++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 3a28282d55..b1453e3f49 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -57,6 +57,9 @@ def err_fe_pch_malformed_block : Error< "malformed block record in PCH file: '%0'">, DefaultFatal; def err_fe_pch_error_at_end_block : Error< "error at end of module block in PCH file: '%0'">, DefaultFatal; +def err_fe_pch_file_modified : Error< + "file '%0' has been modified since the precompiled header was built">, + DefaultFatal; def err_fe_unable_to_open_output : Error< "unable to open output file '%0': '%1'">; def err_fe_unable_to_open_logfile : Error< diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 6def967c4c..c34f3e2543 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -93,8 +93,7 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag, << Entry->getName() << ErrorStr; Buffer.setInt(true); } else if (FileInfo.st_size != Entry->getSize() || - FileInfo.st_mtime != Entry->getModificationTime() || - FileInfo.st_ino != Entry->getInode()) { + FileInfo.st_mtime != Entry->getModificationTime()) { // Check that the file's size, modification time, and inode are // the same as in the file entry (which may have come from a // stat cache). diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index e659ff047d..8fd81df098 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -905,11 +905,18 @@ PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) { return Failure; } - if (Record.size() < 8) { + if (Record.size() < 10) { Error("source location entry is incorrect"); return Failure; } + if ((off_t)Record[4] != File->getSize() || + (time_t)Record[5] != File->getModificationTime()) { + Diag(diag::err_fe_pch_file_modified) + << Filename; + return Failure; + } + FileID FID = SourceMgr.createFileID(File, SourceLocation::getFromRawEncoding(Record[1]), (SrcMgr::CharacteristicKind)Record[2], @@ -920,10 +927,10 @@ PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) { // Reconstruct header-search information for this file. HeaderFileInfo HFI; - HFI.isImport = Record[4]; - HFI.DirInfo = Record[5]; - HFI.NumIncludes = Record[6]; - HFI.ControllingMacroID = Record[7]; + HFI.isImport = Record[6]; + HFI.DirInfo = Record[7]; + HFI.NumIncludes = Record[8]; + HFI.ControllingMacroID = Record[9]; if (Listener) Listener->ReadHeaderFileInfo(HFI, File->getUID()); break; diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 4752cd3ea6..6c2d1424c8 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -921,6 +921,9 @@ static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives + // FileEntry fields. + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time // HeaderFileInfo fields. Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImport Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // DirInfo @@ -1063,6 +1066,10 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, // The source location entry is a file. The blob associated // with this entry is the file name. + // Emit size/modification time for this file. + Record.push_back(Content->Entry->getSize()); + Record.push_back(Content->Entry->getModificationTime()); + // Emit header-search information associated with this file. HeaderFileInfo HFI; HeaderSearch &HS = PP.getHeaderSearchInfo();