@@ -754,6 +754,88 @@ TEST_F(BackgroundIndexTest, UpdateAfterRestart) {
754754 EXPECT_EQ (CheckRefCount (" waldo" ), 2u );
755755}
756756
757+ // Test that updating a header that's included by multiple source files
758+ // correctly updates all including source files, even if the source files
759+ // themselves did not change.
760+ TEST_F (BackgroundIndexTest, HeaderWithMultipleIncluders) {
761+ MockFS FS;
762+ llvm::StringMap<std::string> Storage;
763+ size_t CacheHits = 0 ;
764+ MemoryShardStorage MSS (Storage, CacheHits);
765+ auto CDB = std::make_unique<OverlayCDB>(/* Base=*/ nullptr );
766+ auto Idx = std::make_unique<BackgroundIndex>(
767+ FS, *CDB, [&](llvm::StringRef) { return &MSS; },
768+ BackgroundIndex::Options{});
769+
770+ // Create a header file containing a function declaration, and two source
771+ // files each containing a call to the function.
772+ FS.Files [testPath (" header.h" )] = R"cpp(
773+ #ifndef TEST_H
774+ #define TEST_H
775+ void waldo(int);
776+ #endif
777+ )cpp" ;
778+ FS.Files [testPath (" a.cc" )] = R"cpp(
779+ #include "header.h"
780+ void f() {
781+ waldo(41);
782+ }
783+ )cpp" ;
784+ FS.Files [testPath (" b.cc" )] = R"cpp(
785+ #include "header.h"
786+ void f() {
787+ waldo(42);
788+ }
789+ )cpp" ;
790+
791+ // Index the files in this state.
792+ tooling::CompileCommand Cmd1;
793+ Cmd1.Filename = " ../a.cc" ;
794+ Cmd1.Directory = testPath (" build" );
795+ Cmd1.CommandLine = {" clang++" , " ../a.cc" , " -fsyntax-only" };
796+ tooling::CompileCommand Cmd2;
797+ Cmd2.Filename = " ../b.cc" ;
798+ Cmd2.Directory = testPath (" build" );
799+ Cmd2.CommandLine = {" clang++" , " ../b.cc" , " -fsyntax-only" };
800+ CDB->setCompileCommand (testPath (" b.cc" ), Cmd2);
801+ ASSERT_TRUE (Idx->blockUntilIdleForTest ());
802+
803+ // Verify that the function 'waldo' has three references in the index
804+ // (the declaration, and the two call sites).
805+ auto CheckRefCount = [&](std::string SymbolName) {
806+ auto Syms = runFuzzyFind (*Idx, SymbolName);
807+ EXPECT_THAT (Syms, UnorderedElementsAre (named (SymbolName)));
808+ auto Sym = *Syms.begin ();
809+ return getRefs (*Idx, Sym.ID ).numRefs ();
810+ };
811+ EXPECT_EQ (CheckRefCount (" waldo" ), 3u );
812+
813+ // Modify the declaration of 'waldo' in a way that changes its SymbolID
814+ // without changing how existing call sites are written. Here, we add
815+ // a new parameter with a default argument.
816+ FS.Files [testPath (" test.h" )] = R"cpp(
817+ #ifndef TEST_H
818+ #define TEST_H
819+ void waldo(int, int = 0);
820+ #endif
821+ )cpp" ;
822+
823+ // Simulate clangd shutting down and restarting, and the background index
824+ // being rebuilt after restart.
825+ Idx = nullptr ;
826+ CDB = std::make_unique<OverlayCDB>(/* Base=*/ nullptr );
827+ Idx = std::make_unique<BackgroundIndex>(
828+ FS, *CDB, [&](llvm::StringRef) { return &MSS; },
829+ BackgroundIndex::Options{});
830+ CDB->setCompileCommand (testPath (" a.cc" ), Cmd1);
831+ CDB->setCompileCommand (testPath (" b.cc" ), Cmd2);
832+ ASSERT_TRUE (Idx->blockUntilIdleForTest ());
833+
834+ // The rebuild should have updated things so that 'waldo' now again has
835+ // three references in the index.
836+ EXPECT_EQ (CheckRefCount (" waldo" ), 3u );
837+ }
838+
757839class BackgroundIndexRebuilderTest : public testing ::Test {
758840protected:
759841 BackgroundIndexRebuilderTest ()
0 commit comments