Revert "Address comments"
authorKadir Cetinkaya <kadircet@google.com>
Thu, 15 Nov 2018 10:34:39 +0000 (10:34 +0000)
committerKadir Cetinkaya <kadircet@google.com>
Thu, 15 Nov 2018 10:34:39 +0000 (10:34 +0000)
This reverts commit 19a39b14eab2b5339325e276262b177357d6b412.

llvm-svn: 346943

clang-tools-extra/clangd/index/Background.cpp
clang-tools-extra/clangd/index/Background.h
clang-tools-extra/unittests/clangd/BackgroundIndexTests.cpp

index ef83abf..a972454 100644 (file)
@@ -56,77 +56,15 @@ getShardPathFromFilePath(llvm::SmallString<128> ShardRoot,
   return ShardRoot;
 }
 
-// Uses disk as a storage for index shards. Creates a directory called
-// ".clangd-index/" under the path provided during initialize.
-// Note: Requires initialize to be called before storing or retrieval.
-// This class is thread-safe.
-class DiskBackedIndexStorage : public BackgroundIndexStorage {
-  llvm::SmallString<128> DiskShardRoot;
-
-public:
-  llvm::Expected<IndexFileIn>
-  retrieveShard(llvm::StringRef ShardIdentifier) const override {
-    auto ShardPath = getShardPathFromFilePath(DiskShardRoot, ShardIdentifier);
-    auto Buffer = MemoryBuffer::getFile(ShardPath);
-    if (!Buffer) {
-      elog("Couldn't retrieve {0}: {1}", ShardPath,
-           Buffer.getError().message());
-      return llvm::make_error<llvm::StringError>(Buffer.getError());
-    }
-    // FIXME: Change readIndexFile to also look at Hash of the source that
-    // generated index and skip if there is a mismatch.
-    return readIndexFile(Buffer->get()->getBuffer());
-  }
-
-  bool storeShard(llvm::StringRef ShardIdentifier,
-                  IndexFileOut Shard) const override {
-    auto ShardPath = getShardPathFromFilePath(DiskShardRoot, ShardIdentifier);
-    std::error_code EC;
-    llvm::raw_fd_ostream OS(ShardPath, EC);
-    if (EC) {
-      elog("Failed to open {0} for writing: {1}", ShardPath, EC.message());
-      return false;
-    }
-    OS << Shard;
-    return true;
-  }
-
-  // Initializes DiskShardRoot to (Directory + ".clangd-index/") which is the
-  // base directory for all shard files. After the initialization succeeds all
-  // subsequent calls are no-op.
-  DiskBackedIndexStorage(llvm::StringRef Directory) : DiskShardRoot(Directory) {
-    sys::path::append(DiskShardRoot, ".clangd-index/");
-    if (!llvm::sys::fs::exists(DiskShardRoot)) {
-      std::error_code OK;
-      std::error_code EC = llvm::sys::fs::create_directory(DiskShardRoot);
-      if (EC != OK) {
-        elog("Failed to create {0}: {1}", DiskShardRoot, EC.message());
-      }
-    }
-  }
-};
-
-SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {
-  SmallString<128> AbsolutePath;
-  if (sys::path::is_absolute(Cmd.Filename)) {
-    AbsolutePath = Cmd.Filename;
-  } else {
-    AbsolutePath = Cmd.Directory;
-    sys::path::append(AbsolutePath, Cmd.Filename);
-  }
-  return AbsolutePath;
-}
-
 } // namespace
 
-BackgroundIndex::BackgroundIndex(Context BackgroundContext,
-                                 StringRef ResourceDir,
-                                 const FileSystemProvider &FSProvider,
-                                 ArrayRef<std::string> URISchemes,
-                                 size_t ThreadPoolSize)
+BackgroundIndex::BackgroundIndex(
+    Context BackgroundContext, StringRef ResourceDir,
+    const FileSystemProvider &FSProvider, ArrayRef<std::string> URISchemes,
+    std::unique_ptr<ShardStorage> IndexShardStorage, size_t ThreadPoolSize)
     : SwapIndex(make_unique<MemIndex>()), ResourceDir(ResourceDir),
       FSProvider(FSProvider), BackgroundContext(std::move(BackgroundContext)),
-      URISchemes(URISchemes) {
+      URISchemes(URISchemes), IndexShardStorage(std::move(IndexShardStorage)) {
   assert(ThreadPoolSize > 0 && "Thread pool size can't be zero.");
   while (ThreadPoolSize--) {
     ThreadPool.emplace_back([this] { run(); });
@@ -185,58 +123,19 @@ void BackgroundIndex::blockUntilIdleForTest() {
 
 void BackgroundIndex::enqueue(StringRef Directory,
                               tooling::CompileCommand Cmd) {
-  auto IndexStorage = BackgroundIndexStorage::getForDirectory(Directory);
-  if (IndexStorage)
-    loadShard(IndexStorage.get(), Cmd);
-  else
-    elog("No index storage for: {0}", Directory);
   {
     std::lock_guard<std::mutex> Lock(QueueMu);
-    enqueueLocked(std::move(Cmd), std::move(IndexStorage));
+    enqueueLocked(std::move(Cmd));
   }
   QueueCV.notify_all();
 }
 
-void BackgroundIndex::loadShard(BackgroundIndexStorage *IndexStorage,
-                                const tooling::CompileCommand &Cmd) {
-  assert(IndexStorage && "No index storage to load from?");
-  auto AbsolutePath = getAbsolutePath(Cmd);
-  auto Shard = IndexStorage->retrieveShard(AbsolutePath);
-  if (Shard) {
-    // FIXME: Updated hashes once we have them in serialized format.
-    // IndexedFileDigests[AbsolutePath] = Hash;
-    IndexedSymbols.update(AbsolutePath,
-                          make_unique<SymbolSlab>(std::move(*Shard->Symbols)),
-                          make_unique<RefSlab>(std::move(*Shard->Refs)));
-
-    vlog("Loaded {0} from storage", AbsolutePath);
-  }
-}
-
-void BackgroundIndex::loadShards(
-    BackgroundIndexStorage *IndexStorage,
-    const std::vector<tooling::CompileCommand> &Cmds) {
-  assert(IndexStorage && "No index storage to load from?");
-  for (const auto &Cmd : Cmds)
-    loadShard(IndexStorage, Cmd);
-  // FIXME: Maybe we should get rid of this one once we start building index
-  // periodically? Especially if we also offload this task onto the queue.
-  vlog("Rebuilding automatic index");
-  reset(IndexedSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge,
-                                  URISchemes));
-}
-
 void BackgroundIndex::enqueueAll(StringRef Directory,
                                  const tooling::CompilationDatabase &CDB) {
   trace::Span Tracer("BackgroundIndexEnqueueCDB");
   // FIXME: this function may be slow. Perhaps enqueue a task to re-read the CDB
   // from disk and enqueue the commands asynchronously?
   auto Cmds = CDB.getAllCompileCommands();
-  auto IndexStorage = BackgroundIndexStorage::getForDirectory(Directory);
-  if (IndexStorage)
-    loadShards(IndexStorage.get(), Cmds);
-  else
-    elog("No index storage for: {0}", Directory);
   SPAN_ATTACH(Tracer, "commands", int64_t(Cmds.size()));
   std::mt19937 Generator(std::random_device{}());
   std::shuffle(Cmds.begin(), Cmds.end(), Generator);
@@ -244,23 +143,26 @@ void BackgroundIndex::enqueueAll(StringRef Directory,
   {
     std::lock_guard<std::mutex> Lock(QueueMu);
     for (auto &Cmd : Cmds)
-      enqueueLocked(std::move(Cmd), IndexStorage);
+      enqueueLocked(std::move(Cmd));
   }
   QueueCV.notify_all();
 }
 
-void BackgroundIndex::enqueueLocked(
-    tooling::CompileCommand Cmd,
-    std::shared_ptr<BackgroundIndexStorage> IndexStorage) {
+void BackgroundIndex::enqueueLocked(tooling::CompileCommand Cmd) {
+  // Initialize storage to project root. Since Initialize is no-op for multiple
+  // calls we can simply call it for each file.
+  if (IndexShardStorage && !IndexShardStorage->initialize(Cmd.Directory)) {
+    elog("Failed to initialize shard storage");
+    IndexShardStorage.reset();
+  }
   Queue.push_back(Bind(
-      [this](tooling::CompileCommand Cmd,
-             std::shared_ptr<BackgroundIndexStorage> IndexStorage) {
+      [this](tooling::CompileCommand Cmd) {
         std::string Filename = Cmd.Filename;
         Cmd.CommandLine.push_back("-resource-dir=" + ResourceDir);
-        if (auto Error = index(std::move(Cmd), IndexStorage.get()))
+        if (auto Error = index(std::move(Cmd)))
           log("Indexing {0} failed: {1}", Filename, std::move(Error));
       },
-      std::move(Cmd), std::move(IndexStorage)));
+      std::move(Cmd)));
 }
 
 // Resolves URI to file paths with cache.
@@ -296,8 +198,7 @@ private:
 /// Given index results from a TU, only update files in \p FilesToUpdate.
 void BackgroundIndex::update(StringRef MainFile, SymbolSlab Symbols,
                              RefSlab Refs,
-                             const StringMap<FileDigest> &FilesToUpdate,
-                             BackgroundIndexStorage *IndexStorage) {
+                             const StringMap<FileDigest> &FilesToUpdate) {
   // Partition symbols/references into files.
   struct File {
     DenseSet<const Symbol *> Symbols;
@@ -349,14 +250,13 @@ void BackgroundIndex::update(StringRef MainFile, SymbolSlab Symbols,
     auto RS = llvm::make_unique<RefSlab>(std::move(Refs).build());
 
     auto Hash = FilesToUpdate.lookup(Path);
-    // We need to store shards before updating the index, since the latter
-    // consumes slabs.
+    // Put shards into storage for subsequent use.
     // FIXME: Store Hash in the Shard.
-    if (IndexStorage) {
+    if (IndexShardStorage) {
       IndexFileOut Shard;
       Shard.Symbols = SS.get();
       Shard.Refs = RS.get();
-      IndexStorage->storeShard(Path, Shard);
+      IndexShardStorage->storeShard(Path, Shard);
     }
 
     std::lock_guard<std::mutex> Lock(DigestsMu);
@@ -370,8 +270,7 @@ void BackgroundIndex::update(StringRef MainFile, SymbolSlab Symbols,
 
 // Creates a filter to not collect index results from files with unchanged
 // digests.
-// \p FileDigests contains file digests for the current indexed files, and all
-// changed files will be added to \p FilesToUpdate.
+// \p FileDigests contains file digests for the current indexed files, and all changed files will be added to \p FilesToUpdate.
 decltype(SymbolCollector::Options::FileFilter) createFileFilter(
     const llvm::StringMap<BackgroundIndex::FileDigest> &FileDigests,
     llvm::StringMap<BackgroundIndex::FileDigest> &FilesToUpdate) {
@@ -400,11 +299,16 @@ decltype(SymbolCollector::Options::FileFilter) createFileFilter(
   };
 }
 
-Error BackgroundIndex::index(tooling::CompileCommand Cmd,
-                             BackgroundIndexStorage *IndexStorage) {
+Error BackgroundIndex::index(tooling::CompileCommand Cmd) {
   trace::Span Tracer("BackgroundIndex");
   SPAN_ATTACH(Tracer, "file", Cmd.Filename);
-  SmallString<128> AbsolutePath = getAbsolutePath(Cmd);
+  SmallString<128> AbsolutePath;
+  if (sys::path::is_absolute(Cmd.Filename)) {
+    AbsolutePath = Cmd.Filename;
+  } else {
+    AbsolutePath = Cmd.Directory;
+    sys::path::append(AbsolutePath, Cmd.Filename);
+  }
 
   auto FS = FSProvider.getFileSystem();
   auto Buf = FS->getBufferForFile(AbsolutePath);
@@ -419,6 +323,18 @@ Error BackgroundIndex::index(tooling::CompileCommand Cmd,
     if (IndexedFileDigests.lookup(AbsolutePath) == Hash) {
       vlog("No need to index {0}, already up to date", AbsolutePath);
       return Error::success();
+    } else if (IndexShardStorage) { // Check if shard storage has the index.
+      auto Shard = IndexShardStorage->retrieveShard(AbsolutePath, Hash);
+      if (Shard) {
+        // FIXME: We might still want to re-index headers.
+        IndexedFileDigests[AbsolutePath] = Hash;
+        IndexedSymbols.update(
+            AbsolutePath, make_unique<SymbolSlab>(std::move(*Shard->Symbols)),
+            make_unique<RefSlab>(std::move(*Shard->Refs)));
+
+        vlog("Loaded {0} from storage", AbsolutePath);
+        return Error::success();
+      }
     }
 
     DigestsSnapshot = IndexedFileDigests;
@@ -468,8 +384,7 @@ Error BackgroundIndex::index(tooling::CompileCommand Cmd,
       Symbols.size(), Refs.numRefs());
   SPAN_ATTACH(Tracer, "symbols", int(Symbols.size()));
   SPAN_ATTACH(Tracer, "refs", int(Refs.numRefs()));
-  update(AbsolutePath, std::move(Symbols), std::move(Refs), FilesToUpdate,
-         IndexStorage);
+  update(AbsolutePath, std::move(Symbols), std::move(Refs), FilesToUpdate);
   {
     // Make sure hash for the main file is always updated even if there is no
     // index data in it.
@@ -486,8 +401,59 @@ Error BackgroundIndex::index(tooling::CompileCommand Cmd,
   return Error::success();
 }
 
-std::function<std::shared_ptr<BackgroundIndexStorage>(llvm::StringRef)>
-    BackgroundIndexStorage::Factory = nullptr;
+llvm::Expected<IndexFileIn>
+DiskShardStorage::retrieveShard(llvm::StringRef ShardIdentifier,
+                                FileDigest Hash) const {
+  assert(Initialized && "Not initialized?");
+  llvm::SmallString<128> ShardPath;
+  {
+    std::lock_guard<std::mutex> Lock(DiskShardRootMu);
+    ShardPath = getShardPathFromFilePath(DiskShardRoot, ShardIdentifier);
+  }
+  auto Buffer = MemoryBuffer::getFile(ShardPath);
+  if (!Buffer) {
+    elog("Couldn't retrieve {0}: {1}", ShardPath, Buffer.getError().message());
+    return llvm::make_error<llvm::StringError>(Buffer.getError());
+  }
+  // FIXME: Change readIndexFile to also look at Hash of the source that
+  // generated index and skip if there is a mismatch.
+  return readIndexFile(Buffer->get()->getBuffer());
+}
+
+bool DiskShardStorage::storeShard(llvm::StringRef ShardIdentifier,
+                                  IndexFileOut Shard) const {
+  assert(Initialized && "Not initialized?");
+  llvm::SmallString<128> ShardPath;
+  {
+    std::lock_guard<std::mutex> Lock(DiskShardRootMu);
+    ShardPath = getShardPathFromFilePath(DiskShardRoot, ShardIdentifier);
+  }
+  std::error_code EC;
+  llvm::raw_fd_ostream OS(ShardPath, EC);
+  if (EC) {
+    elog("Failed to open {0} for writing: {1}", ShardPath, EC.message());
+    return false;
+  }
+  OS << Shard;
+  return true;
+}
+
+bool DiskShardStorage::initialize(llvm::StringRef Directory) {
+  if (Initialized)
+    return true;
+  std::lock_guard<std::mutex> Lock(DiskShardRootMu);
+  DiskShardRoot = Directory;
+  sys::path::append(DiskShardRoot, ".clangd-index/");
+  if (!llvm::sys::fs::exists(DiskShardRoot)) {
+    std::error_code OK;
+    std::error_code EC = llvm::sys::fs::create_directory(DiskShardRoot);
+    if (EC != OK) {
+      elog("Failed to create {0}: {1}", DiskShardRoot, EC.message());
+      return Initialized = false;
+    }
+  }
+  return Initialized = true;
+}
 
 } // namespace clangd
 } // namespace clang
index a96e20e..bff6304 100644 (file)
 namespace clang {
 namespace clangd {
 
-// Handles storage and retrieval of index shards.
-class BackgroundIndexStorage {
-private:
-  static std::function<std::shared_ptr<BackgroundIndexStorage>(llvm::StringRef)>
-      Factory;
-
+// Base class for Shard Storage operations. See DiskShardStorage for more info.
+class ShardStorage {
 public:
   using FileDigest = decltype(llvm::SHA1::hash({}));
-
-  // Stores given shard associationg with ShardIdentifier, which can be
-  // retrieved later on with the same identifier.
   virtual bool storeShard(llvm::StringRef ShardIdentifier,
                           IndexFileOut Shard) const = 0;
-
-  // Retrieves the shard if found, also returns hash for the source file that
-  // generated this shard.
   virtual llvm::Expected<IndexFileIn>
-  retrieveShard(llvm::StringRef ShardIdentifier) const = 0;
-
-  template <typename T> static void setStorageFactory(T Factory) {
-    BackgroundIndexStorage::Factory = Factory;
-  }
-
-  static std::shared_ptr<BackgroundIndexStorage>
-  getForDirectory(llvm::StringRef Directory) {
-    if (!Factory)
-      return nullptr;
-    return Factory(Directory);
-  }
+  retrieveShard(llvm::StringRef ShardIdentifier, FileDigest Hash) const = 0;
+  virtual bool initialize(llvm::StringRef Directory) = 0;
 };
 
 // Builds an in-memory index by by running the static indexer action over
@@ -68,6 +48,7 @@ public:
   // FIXME: resource-dir injection should be hoisted somewhere common.
   BackgroundIndex(Context BackgroundContext, llvm::StringRef ResourceDir,
                   const FileSystemProvider &, ArrayRef<std::string> URISchemes,
+                  std::unique_ptr<ShardStorage> IndexShardStorage = nullptr,
                   size_t ThreadPoolSize = llvm::hardware_concurrency());
   ~BackgroundIndex(); // Blocks while the current task finishes.
 
@@ -91,22 +72,17 @@ public:
 private:
   /// Given index results from a TU, only update files in \p FilesToUpdate.
   void update(llvm::StringRef MainFile, SymbolSlab Symbols, RefSlab Refs,
-              const llvm::StringMap<FileDigest> &FilesToUpdate,
-              BackgroundIndexStorage *IndexStorage);
-  void loadShard(BackgroundIndexStorage *IndexStorage,
-                 const tooling::CompileCommand &Cmd);
-  void loadShards(BackgroundIndexStorage *IndexStorage,
-                  const std::vector<tooling::CompileCommand> &Cmds);
+              const llvm::StringMap<FileDigest> &FilesToUpdate);
 
   // configuration
   std::string ResourceDir;
   const FileSystemProvider &FSProvider;
   Context BackgroundContext;
   std::vector<std::string> URISchemes;
+  std::unique_ptr<ShardStorage> IndexShardStorage;
 
   // index state
-  llvm::Error index(tooling::CompileCommand,
-                    BackgroundIndexStorage *IndexStorage);
+  llvm::Error index(tooling::CompileCommand);
 
   FileSymbols IndexedSymbols;
   llvm::StringMap<FileDigest> IndexedFileDigests; // Key is absolute file path.
@@ -115,8 +91,7 @@ private:
   // queue management
   using Task = std::function<void()>;
   void run(); // Main loop executed by Thread. Runs tasks from Queue.
-  void enqueueLocked(tooling::CompileCommand Cmd,
-                     std::shared_ptr<BackgroundIndexStorage> IndexStorage);
+  void enqueueLocked(tooling::CompileCommand Cmd);
   std::mutex QueueMu;
   unsigned NumActiveTasks = 0; // Only idle when queue is empty *and* no tasks.
   std::condition_variable QueueCV;
@@ -125,6 +100,30 @@ private:
   std::vector<std::thread> ThreadPool; // FIXME: Abstract this away.
 };
 
+// Handles storage and retrieval of index shards into disk. Requires Initialize
+// to be called before storing or retrieval. Creates a directory called
+// ".clangd-index/" under the path provided during initialize. This class is
+// thread-safe.
+class DiskShardStorage : public ShardStorage {
+  mutable std::mutex DiskShardRootMu;
+  llvm::SmallString<128> DiskShardRoot;
+  bool Initialized;
+
+public:
+  // Retrieves the shard if found and contents are consistent with the provided
+  // Hash.
+  llvm::Expected<IndexFileIn> retrieveShard(llvm::StringRef ShardIdentifier,
+                                            FileDigest Hash) const;
+
+  // Stores given shard with name ShardIdentifier under initialized directory.
+  bool storeShard(llvm::StringRef ShardIdentifier, IndexFileOut Shard) const;
+
+  // Initializes DiskShardRoot to (Directory + ".clangd-index/") which is the
+  // base directory for all shard files. After the initialization succeeds all
+  // subsequent calls or no-op.
+  bool initialize(llvm::StringRef Directory);
+};
+
 } // namespace clangd
 } // namespace clang
 
index eb3a19b..ee8aa67 100644 (file)
@@ -79,7 +79,7 @@ TEST(BackgroundIndexTest, IndexTwoFiles) {
 }
 
 TEST(BackgroundIndexTest, ShardStorageTest) {
-  class MemoryShardStorage : public BackgroundIndexStorage {
+  class MemoryShardStorage : public ShardStorage {
     mutable std::mutex StorageMu;
     llvm::StringMap<std::string> &Storage;
     size_t &CacheHits;
@@ -88,8 +88,7 @@ TEST(BackgroundIndexTest, ShardStorageTest) {
     MemoryShardStorage(llvm::StringMap<std::string> &Storage, size_t &CacheHits)
         : Storage(Storage), CacheHits(CacheHits) {}
 
-    bool storeShard(llvm::StringRef ShardIdentifier,
-                    IndexFileOut Shard) const override {
+    bool storeShard(llvm::StringRef ShardIdentifier, IndexFileOut Shard) const {
       std::lock_guard<std::mutex> Lock(StorageMu);
       std::string &str = Storage[ShardIdentifier];
       llvm::raw_string_ostream OS(str);
@@ -97,8 +96,8 @@ TEST(BackgroundIndexTest, ShardStorageTest) {
       OS.flush();
       return true;
     }
-    llvm::Expected<IndexFileIn>
-    retrieveShard(llvm::StringRef ShardIdentifier) const override {
+    llvm::Expected<IndexFileIn> retrieveShard(llvm::StringRef ShardIdentifier,
+                                              FileDigest Hash) const {
       std::lock_guard<std::mutex> Lock(StorageMu);
       if (Storage.find(ShardIdentifier) == Storage.end())
         return llvm::make_error<llvm::StringError>(
@@ -119,21 +118,17 @@ TEST(BackgroundIndexTest, ShardStorageTest) {
       )cpp";
   FS.Files[testPath("root/A.cc")] =
       "#include \"A.h\"\nvoid g() { (void)common; }";
-
   llvm::StringMap<std::string> Storage;
   size_t CacheHits = 0;
-  BackgroundIndexStorage::setStorageFactory(
-      [&Storage, &CacheHits](llvm::StringRef) {
-        return std::make_shared<MemoryShardStorage>(Storage, CacheHits);
-      });
-
   tooling::CompileCommand Cmd;
   Cmd.Filename = testPath("root/A.cc");
   Cmd.Directory = testPath("root");
   Cmd.CommandLine = {"clang++", testPath("root/A.cc")};
-  // Check nothing is loaded from Storage, but A.cc and A.h has been stored.
   {
-    BackgroundIndex Idx(Context::empty(), "", FS, /*URISchemes=*/{"unittest"});
+    BackgroundIndex Idx(
+        Context::empty(), "", FS, /*URISchemes=*/{"unittest"},
+        /*IndexShardStorage=*/
+        llvm::make_unique<MemoryShardStorage>(Storage, CacheHits));
     Idx.enqueue(testPath("root"), Cmd);
     Idx.blockUntilIdleForTest();
   }
@@ -142,9 +137,11 @@ TEST(BackgroundIndexTest, ShardStorageTest) {
   EXPECT_NE(Storage.find(testPath("root/A.h")), Storage.end());
   EXPECT_NE(Storage.find(testPath("root/A.cc")), Storage.end());
 
-  // Check A.cc has been loaded from cache.
   {
-    BackgroundIndex Idx(Context::empty(), "", FS, /*URISchemes=*/{"unittest"});
+    BackgroundIndex Idx(
+        Context::empty(), "", FS, /*URISchemes=*/{"unittest"},
+        /*IndexShardStorage=*/
+        llvm::make_unique<MemoryShardStorage>(Storage, CacheHits));
     Idx.enqueue(testPath("root"), Cmd);
     Idx.blockUntilIdleForTest();
   }
@@ -152,6 +149,7 @@ TEST(BackgroundIndexTest, ShardStorageTest) {
   EXPECT_EQ(Storage.size(), 2U);
   EXPECT_NE(Storage.find(testPath("root/A.h")), Storage.end());
   EXPECT_NE(Storage.find(testPath("root/A.cc")), Storage.end());
+  // B_CC is dropped as we don't collect symbols from A.h in this compilation.
 }
 
 } // namespace clangd