Skip to content

Commit 4fb1f2e

Browse files
authored
[clangd] Fix the modification detection logic in ClangdLSPServer::applyConfiguration. (llvm#115438)
Prior to this, the "old != new" check would always evaluate to true because it was comparing a pre-mangling new command to a post-mangling old command.
1 parent 1799d57 commit 4fb1f2e

File tree

4 files changed

+31
-23
lines changed

4 files changed

+31
-23
lines changed

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,15 +1419,12 @@ void ClangdLSPServer::applyConfiguration(
14191419
const ConfigurationSettings &Settings) {
14201420
// Per-file update to the compilation database.
14211421
llvm::StringSet<> ModifiedFiles;
1422-
for (auto &Entry : Settings.compilationDatabaseChanges) {
1423-
PathRef File = Entry.first;
1424-
auto Old = CDB->getCompileCommand(File);
1425-
auto New =
1426-
tooling::CompileCommand(std::move(Entry.second.workingDirectory), File,
1427-
std::move(Entry.second.compilationCommand),
1422+
for (auto &[File, Command] : Settings.compilationDatabaseChanges) {
1423+
auto Cmd =
1424+
tooling::CompileCommand(std::move(Command.workingDirectory), File,
1425+
std::move(Command.compilationCommand),
14281426
/*Output=*/"");
1429-
if (Old != New) {
1430-
CDB->setCompileCommand(File, std::move(New));
1427+
if (CDB->setCompileCommand(File, std::move(Cmd))) {
14311428
ModifiedFiles.insert(File);
14321429
}
14331430
}

clang-tools-extra/clangd/GlobalCompilationDatabase.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -807,20 +807,27 @@ tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const {
807807
return Cmd;
808808
}
809809

810-
void OverlayCDB::setCompileCommand(PathRef File,
810+
bool OverlayCDB::setCompileCommand(PathRef File,
811811
std::optional<tooling::CompileCommand> Cmd) {
812812
// We store a canonical version internally to prevent mismatches between set
813813
// and get compile commands. Also it assures clients listening to broadcasts
814814
// doesn't receive different names for the same file.
815815
std::string CanonPath = removeDots(File);
816816
{
817817
std::unique_lock<std::mutex> Lock(Mutex);
818-
if (Cmd)
819-
Commands[CanonPath] = std::move(*Cmd);
820-
else
818+
if (Cmd) {
819+
if (auto [It, Inserted] =
820+
Commands.try_emplace(CanonPath, std::move(*Cmd));
821+
!Inserted) {
822+
if (It->second == *Cmd)
823+
return false;
824+
It->second = *Cmd;
825+
}
826+
} else
821827
Commands.erase(CanonPath);
822828
}
823829
OnCommandChanged.broadcast({CanonPath});
830+
return true;
824831
}
825832

826833
DelegatingCDB::DelegatingCDB(const GlobalCompilationDatabase *Base)

clang-tools-extra/clangd/GlobalCompilationDatabase.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ class OverlayCDB : public DelegatingCDB {
203203
tooling::CompileCommand getFallbackCommand(PathRef File) const override;
204204

205205
/// Sets or clears the compilation command for a particular file.
206-
void
206+
/// Returns true if the command was changed (including insertion and removal),
207+
/// false if it was unchanged.
208+
bool
207209
setCompileCommand(PathRef File,
208210
std::optional<tooling::CompileCommand> CompilationCommand);
209211

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,13 @@ TEST_F(OverlayCDBTest, GetCompileCommand) {
9292
EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), std::nullopt);
9393

9494
auto Override = cmd(testPath("foo.cc"), "-DA=3");
95-
CDB.setCompileCommand(testPath("foo.cc"), Override);
95+
EXPECT_TRUE(CDB.setCompileCommand(testPath("foo.cc"), Override));
96+
EXPECT_FALSE(CDB.setCompileCommand(testPath("foo.cc"), Override));
9697
EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine,
9798
Contains("-DA=3"));
9899
EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), std::nullopt);
99-
CDB.setCompileCommand(testPath("missing.cc"), Override);
100+
EXPECT_TRUE(CDB.setCompileCommand(testPath("missing.cc"), Override));
101+
EXPECT_FALSE(CDB.setCompileCommand(testPath("missing.cc"), Override));
100102
EXPECT_THAT(CDB.getCompileCommand(testPath("missing.cc"))->CommandLine,
101103
Contains("-DA=3"));
102104
}
@@ -111,7 +113,7 @@ TEST_F(OverlayCDBTest, NoBase) {
111113
OverlayCDB CDB(nullptr, {"-DA=6"});
112114
EXPECT_EQ(CDB.getCompileCommand(testPath("bar.cc")), std::nullopt);
113115
auto Override = cmd(testPath("bar.cc"), "-DA=5");
114-
CDB.setCompileCommand(testPath("bar.cc"), Override);
116+
EXPECT_TRUE(CDB.setCompileCommand(testPath("bar.cc"), Override));
115117
EXPECT_THAT(CDB.getCompileCommand(testPath("bar.cc"))->CommandLine,
116118
Contains("-DA=5"));
117119

@@ -128,10 +130,10 @@ TEST_F(OverlayCDBTest, Watch) {
128130
Changes.push_back(ChangedFiles);
129131
});
130132

131-
Inner.setCompileCommand("A.cpp", tooling::CompileCommand());
132-
Outer.setCompileCommand("B.cpp", tooling::CompileCommand());
133-
Inner.setCompileCommand("A.cpp", std::nullopt);
134-
Outer.setCompileCommand("C.cpp", std::nullopt);
133+
EXPECT_TRUE(Inner.setCompileCommand("A.cpp", tooling::CompileCommand()));
134+
EXPECT_TRUE(Outer.setCompileCommand("B.cpp", tooling::CompileCommand()));
135+
EXPECT_TRUE(Inner.setCompileCommand("A.cpp", std::nullopt));
136+
EXPECT_TRUE(Outer.setCompileCommand("C.cpp", std::nullopt));
135137
EXPECT_THAT(Changes, ElementsAre(ElementsAre("A.cpp"), ElementsAre("B.cpp"),
136138
ElementsAre("A.cpp"), ElementsAre("C.cpp")));
137139
}
@@ -151,7 +153,7 @@ TEST_F(OverlayCDBTest, Adjustments) {
151153
tooling::CompileCommand BarCommand;
152154
BarCommand.Filename = testPath("bar.cc");
153155
BarCommand.CommandLine = {"clang++", "-DB=1", testPath("bar.cc")};
154-
CDB.setCompileCommand(testPath("bar.cc"), BarCommand);
156+
EXPECT_TRUE(CDB.setCompileCommand(testPath("bar.cc"), BarCommand));
155157
Cmd = *CDB.getCompileCommand(testPath("bar.cc"));
156158
EXPECT_THAT(
157159
Cmd.CommandLine,
@@ -412,7 +414,7 @@ TEST(GlobalCompilationDatabaseTest, NonCanonicalFilenames) {
412414

413415
llvm::SmallString<128> Root(testRoot());
414416
llvm::sys::path::append(Root, "build", "..", "a.cc");
415-
DB.setCompileCommand(Root.str(), tooling::CompileCommand());
417+
EXPECT_TRUE(DB.setCompileCommand(Root.str(), tooling::CompileCommand()));
416418
EXPECT_THAT(DiscoveredFiles, UnorderedElementsAre(testPath("a.cc")));
417419
DiscoveredFiles.clear();
418420

@@ -432,7 +434,7 @@ TEST_F(OverlayCDBTest, GetProjectInfo) {
432434
EXPECT_EQ(DB.getProjectInfo(Header)->SourceRoot, testRoot());
433435

434436
// Shouldn't change after an override.
435-
DB.setCompileCommand(File, tooling::CompileCommand());
437+
EXPECT_TRUE(DB.setCompileCommand(File, tooling::CompileCommand()));
436438
EXPECT_EQ(DB.getProjectInfo(File)->SourceRoot, testRoot());
437439
EXPECT_EQ(DB.getProjectInfo(Header)->SourceRoot, testRoot());
438440
}

0 commit comments

Comments
 (0)