Skip to content

Commit af6254f

Browse files
committed
[clang][modules] Detect invalidation of SDKSettings.json
1 parent b38c103 commit af6254f

File tree

4 files changed

+80
-1
lines changed

4 files changed

+80
-1
lines changed

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const unsigned VERSION_MAJOR = 34;
5454
/// for the previous version could still support reading the new
5555
/// version by ignoring new kinds of subblocks), this number
5656
/// should be increased.
57-
const unsigned VERSION_MINOR = 0;
57+
const unsigned VERSION_MINOR = 1;
5858

5959
/// An ID number that refers to an identifier in an AST file.
6060
///
@@ -386,6 +386,10 @@ enum ControlRecordTypes {
386386
/// Record code for the (optional) include-tree ID for implicit modules
387387
/// built with the dependency scanner.
388388
CAS_INCLUDE_TREE_ID,
389+
390+
/// Record code for the (optional) modification timestamp of the
391+
/// SDKSettings.json file.
392+
SDK_SETTINGS_JSON_TIMESTAMP,
389393
};
390394

391395
/// Record types that occur within the options block inside

clang/lib/Serialization/ASTReader.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3507,6 +3507,29 @@ ASTReader::ReadControlBlock(ModuleFile &F,
35073507
return OutOfDate;
35083508
}
35093509
break;
3510+
3511+
case SDK_SETTINGS_JSON_TIMESTAMP: {
3512+
time_t ExpectedModTime = Record[0];
3513+
time_t ActualModTime = 0;
3514+
StringRef Sysroot =
3515+
PP.getHeaderSearchInfo().getHeaderSearchOpts().Sysroot;
3516+
if (!Sysroot.empty()) {
3517+
SmallString<128> SDKSettingsJSON = Sysroot;
3518+
llvm::sys::path::append(SDKSettingsJSON, "SDKSettings.json");
3519+
if (auto FE = PP.getFileManager().getOptionalFileRef(SDKSettingsJSON))
3520+
ActualModTime = FE->getModificationTime();
3521+
}
3522+
if (ActualModTime && ExpectedModTime &&
3523+
ActualModTime != ExpectedModTime) {
3524+
if (!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities))
3525+
Diag(diag::err_fe_ast_file_modified)
3526+
<< "SDKSettings.json" << moduleKindForDiagnostic(F.Kind)
3527+
<< F.FileName << 1 << 1 << llvm::itostr(ExpectedModTime)
3528+
<< llvm::itostr(ActualModTime);
3529+
return OutOfDate;
3530+
}
3531+
break;
3532+
}
35103533
}
35113534
}
35123535
}

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ void ASTWriter::WriteBlockInfoBlock() {
917917
RECORD(MODULE_CACHE_KEY);
918918
RECORD(CASFS_ROOT_ID);
919919
RECORD(CAS_INCLUDE_TREE_ID);
920+
RECORD(SDK_SETTINGS_JSON_TIMESTAMP);
920921

921922
BLOCK(OPTIONS_BLOCK);
922923
RECORD(LANGUAGE_OPTIONS);
@@ -1615,6 +1616,20 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
16151616
Stream.EmitRecordWithBlob(AbbrevCode, Record, *ID);
16161617
}
16171618

1619+
time_t SDKSettingsModTime = 0;
1620+
StringRef Sysroot = PP.getHeaderSearchInfo().getHeaderSearchOpts().Sysroot;
1621+
if (!Sysroot.empty()) {
1622+
SmallString<128> SDKSettingsJSON = Sysroot;
1623+
llvm::sys::path::append(SDKSettingsJSON, "SDKSettings.json");
1624+
if (auto FE = PP.getFileManager().getOptionalFileRef(SDKSettingsJSON))
1625+
SDKSettingsModTime = FE->getModificationTime();
1626+
}
1627+
if (SDKSettingsModTime) {
1628+
Record.clear();
1629+
Record.push_back(SDKSettingsModTime);
1630+
Stream.EmitRecord(SDK_SETTINGS_JSON_TIMESTAMP, Record);
1631+
}
1632+
16181633
// Imports
16191634
if (Chain) {
16201635
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// This test checks that the module cache gets invalidated when the
2+
// SDKSettings.json file changes. This prevents "file changed during build"
3+
// errors when the TU does get rescanned and recompiled.
4+
5+
// REQUIRES: ondisk_cas
6+
7+
// RUN: rm -rf %t
8+
// RUN: split-file %s %t
9+
10+
//--- sdk/SDKSettings.json
11+
{
12+
"Version": "11.0",
13+
"MaximumDeploymentTarget": "11.0.99"
14+
}
15+
16+
//--- module.modulemap
17+
module M { header "M.h" }
18+
//--- M.h
19+
//--- tu.c
20+
#include "M.h"
21+
22+
// RUN: clang-scan-deps -format experimental-include-tree-full -cas-path %t/cas -o %t/deps_clean.json \
23+
// RUN: -- %clang -target x86_64-apple-macos11 -isysroot %t/sdk \
24+
// RUN: -c %t/tu.c -o %t/tu.o -fmodules -fmodules-cache-path=%t/cache
25+
26+
// RUN: sleep 1
27+
// RUN: echo " " >> %t/sdk/SDKSettings.json
28+
// RUN: echo " " >> %t/tu.c
29+
30+
// RUN: clang-scan-deps -format experimental-include-tree-full -cas-path %t/cas -o %t/deps_incremental.json \
31+
// RUN: -- %clang -target x86_64-apple-macos11 -isysroot %t/sdk \
32+
// RUN: -c %t/tu.c -o %t/tu.o -fmodules -fmodules-cache-path=%t/cache
33+
34+
// RUN: %deps-to-rsp %t/deps_incremental.json --module-name M > %t/M.rsp
35+
// RUN: %deps-to-rsp %t/deps_incremental.json --tu-index 0 > %t/tu.rsp
36+
// RUN: %clang @%t/M.rsp
37+
// RUN: %clang @%t/tu.rsp

0 commit comments

Comments
 (0)