Skip to content

Commit c959da9

Browse files
committed
[clangd] Only publish preamble after rebuilds
Don't invoke parsing callback for preamble if clangd is using a previously built one. Differential Revision: https://reviews.llvm.org/D112137
1 parent 3efd2a0 commit c959da9

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

clang-tools-extra/clangd/TUScheduler.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -901,15 +901,17 @@ void ASTWorker::runWithAST(
901901
void PreambleThread::build(Request Req) {
902902
assert(Req.CI && "Got preamble request with null compiler invocation");
903903
const ParseInputs &Inputs = Req.Inputs;
904+
bool ReusedPreamble = false;
904905

905906
Status.update([&](TUStatus &Status) {
906907
Status.PreambleActivity = PreambleAction::Building;
907908
});
908-
auto _ = llvm::make_scope_exit([this, &Req] {
909+
auto _ = llvm::make_scope_exit([this, &Req, &ReusedPreamble] {
909910
ASTPeer.updatePreamble(std::move(Req.CI), std::move(Req.Inputs),
910911
LatestBuild, std::move(Req.CIDiags),
911912
std::move(Req.WantDiags));
912-
Callbacks.onPreamblePublished(FileName);
913+
if (!ReusedPreamble)
914+
Callbacks.onPreamblePublished(FileName);
913915
});
914916

915917
if (!LatestBuild || Inputs.ForceRebuild) {
@@ -918,6 +920,7 @@ void PreambleThread::build(Request Req) {
918920
} else if (isPreambleCompatible(*LatestBuild, Inputs, FileName, *Req.CI)) {
919921
vlog("Reusing preamble version {0} for version {1} of {2}",
920922
LatestBuild->Version, Inputs.Version, FileName);
923+
ReusedPreamble = true;
921924
return;
922925
} else {
923926
vlog("Rebuilding invalidated preamble for {0} version {1} (previous was "

clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,32 @@ TEST_F(TUSchedulerTests, AsyncPreambleThread) {
11651165
Ready.notify();
11661166
}
11671167

1168+
TEST_F(TUSchedulerTests, OnlyPublishWhenPreambleIsBuilt) {
1169+
struct PreamblePublishCounter : public ParsingCallbacks {
1170+
PreamblePublishCounter(int &PreamblePublishCount)
1171+
: PreamblePublishCount(PreamblePublishCount) {}
1172+
void onPreamblePublished(PathRef File) override { ++PreamblePublishCount; }
1173+
int &PreamblePublishCount;
1174+
};
1175+
1176+
int PreamblePublishCount = 0;
1177+
TUScheduler S(CDB, optsForTest(),
1178+
std::make_unique<PreamblePublishCounter>(PreamblePublishCount));
1179+
1180+
Path File = testPath("foo.cpp");
1181+
S.update(File, getInputs(File, ""), WantDiagnostics::Auto);
1182+
S.blockUntilIdle(timeoutSeconds(10));
1183+
EXPECT_EQ(PreamblePublishCount, 1);
1184+
// Same contents, no publish.
1185+
S.update(File, getInputs(File, ""), WantDiagnostics::Auto);
1186+
S.blockUntilIdle(timeoutSeconds(10));
1187+
EXPECT_EQ(PreamblePublishCount, 1);
1188+
// New contents, should publish.
1189+
S.update(File, getInputs(File, "#define FOO"), WantDiagnostics::Auto);
1190+
S.blockUntilIdle(timeoutSeconds(10));
1191+
EXPECT_EQ(PreamblePublishCount, 2);
1192+
}
1193+
11681194
// If a header file is missing from the CDB (or inferred using heuristics), and
11691195
// it's included by another open file, then we parse it using that files flags.
11701196
TEST_F(TUSchedulerTests, IncluderCache) {

0 commit comments

Comments
 (0)