Skip to content

Commit df7b6b9

Browse files
committed
Extend diagnostic for out of date AST input file.
If the size has changed, list the old and new sizes; if the mtime has changed, list the old and new mtimes (as raw time_t values).
1 parent 2de2dbe commit df7b6b9

File tree

4 files changed

+29
-17
lines changed

4 files changed

+29
-17
lines changed

clang/include/clang/Basic/DiagnosticSerializationKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def err_fe_pch_malformed_block : Error<
2020
def err_fe_ast_file_modified : Error<
2121
"file '%0' has been modified since the "
2222
"%select{precompiled header|module file|AST file}1 '%2' was built"
23-
": %select{size|mtime|content}3 changed">,
23+
": %select{size|mtime|content}3 changed%select{| (was %5, now %6)}4">,
2424
DefaultFatal;
2525
def err_fe_pch_file_overridden : Error<
2626
"file '%0' from the precompiled header has been overridden">;

clang/lib/Serialization/ASTReader.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,46 +2380,55 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
23802380
}
23812381
}
23822382

2383-
enum ModificationType {
2384-
Size,
2385-
ModTime,
2386-
Content,
2387-
None,
2383+
struct Change {
2384+
enum ModificationKind {
2385+
Size,
2386+
ModTime,
2387+
Content,
2388+
None,
2389+
} Kind;
2390+
llvm::Optional<int64_t> Old = llvm::None;
2391+
llvm::Optional<int64_t> New = llvm::None;
23882392
};
23892393
auto HasInputFileChanged = [&]() {
23902394
if (StoredSize != File->getSize())
2391-
return ModificationType::Size;
2395+
return Change{Change::Size, StoredSize, File->getSize()};
23922396
if (!shouldDisableValidationForFile(F) && StoredTime &&
23932397
StoredTime != File->getModificationTime()) {
2398+
Change MTimeChange = {Change::ModTime, StoredTime,
2399+
File->getModificationTime()};
2400+
23942401
// In case the modification time changes but not the content,
23952402
// accept the cached file as legit.
23962403
if (ValidateASTInputFilesContent &&
23972404
StoredContentHash != static_cast<uint64_t>(llvm::hash_code(-1))) {
23982405
auto MemBuffOrError = FileMgr.getBufferForFile(File);
23992406
if (!MemBuffOrError) {
24002407
if (!Complain)
2401-
return ModificationType::ModTime;
2408+
return MTimeChange;
24022409
std::string ErrorStr = "could not get buffer for file '";
24032410
ErrorStr += File->getName();
24042411
ErrorStr += "'";
24052412
Error(ErrorStr);
2406-
return ModificationType::ModTime;
2413+
return MTimeChange;
24072414
}
24082415

2416+
// FIXME: hash_value is not guaranteed to be stable!
24092417
auto ContentHash = hash_value(MemBuffOrError.get()->getBuffer());
24102418
if (StoredContentHash == static_cast<uint64_t>(ContentHash))
2411-
return ModificationType::None;
2412-
return ModificationType::Content;
2419+
return Change{Change::None};
2420+
2421+
return Change{Change::Content};
24132422
}
2414-
return ModificationType::ModTime;
2423+
return MTimeChange;
24152424
}
2416-
return ModificationType::None;
2425+
return Change{Change::None};
24172426
};
24182427

24192428
bool IsOutOfDate = false;
24202429
auto FileChange = HasInputFileChanged();
24212430
// For an overridden file, there is nothing to validate.
2422-
if (!Overridden && FileChange != ModificationType::None) {
2431+
if (!Overridden && FileChange.Kind != Change::None) {
24232432
if (Complain && !Diags.isDiagnosticInFlight()) {
24242433
// Build a list of the PCH imports that got us here (in reverse).
24252434
SmallVector<ModuleFile *, 4> ImportStack(1, &F);
@@ -2430,7 +2439,10 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
24302439
StringRef TopLevelPCHName(ImportStack.back()->FileName);
24312440
Diag(diag::err_fe_ast_file_modified)
24322441
<< Filename << moduleKindForDiagnostic(ImportStack.back()->Kind)
2433-
<< TopLevelPCHName << FileChange;
2442+
<< TopLevelPCHName << FileChange.Kind
2443+
<< (FileChange.Old && FileChange.New)
2444+
<< llvm::itostr(FileChange.Old.getValueOr(0))
2445+
<< llvm::itostr(FileChange.New.getValueOr(0));
24342446

24352447
// Print the import stack.
24362448
if (ImportStack.size() > 1) {

clang/test/PCH/include-timestamp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ void g() { f(); }
3131
// CHECK-BITCODE-TIMESTAMP-ON: <INPUT_FILE abbrevid={{.*}} op0={{.*}} op1={{.*}} op2={{[^0]}}
3232
// CHECK-BITCODE-TIMESTAMP-OFF: <INPUT_FILE abbrevid={{.*}} op0={{.*}} op1={{.*}} op2={{[0]}}
3333

34-
// CHECK-TIMESTAMP: fatal error: file {{.*}} has been modified since the precompiled header {{.*}} was built
34+
// CHECK-TIMESTAMP: fatal error: file {{.*}} has been modified since the precompiled header {{.*}} was built: mtime changed (was {{.*}}, now {{.*}})

clang/test/PCH/verify_pch.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// RUN: echo ' ' >> %t.h
1818
// RUN: not %clang_cc1 -isystem %t/usr/include -verify-pch %t.pch 2> %t.log.2
1919
// RUN: FileCheck -check-prefix=CHECK-STALE-DEP %s < %t.log.2
20-
// CHECK-STALE-DEP: file '{{.*}}.h' has been modified since the precompiled header '{{.*}}.pch' was built
20+
// CHECK-STALE-DEP: file '{{.*}}.h' has been modified since the precompiled header '{{.*}}.pch' was built: size changed (was {{.*}}, now {{.*}})
2121

2222
// Stale dependency in system header
2323
// RUN: %clang_cc1 -isystem %t/usr/include -x objective-c-header -emit-pch -o %t.pch %t.h

0 commit comments

Comments
 (0)