<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Kadir,<div class=""><br class=""></div><div class="">It seems this commit started causing failures on builds in green dragon, starting from: <a href="http://green.lab.llvm.org/green/job/clang-stage1-configure-RA/52811/" class="">http://green.lab.llvm.org/green/job/clang-stage1-configure-RA/52811/</a></div><div class=""><br class=""></div><div class=""> Can you please take a look, and revert if the fix isn’t straight forward.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Amara<br class=""><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jan 10, 2019, at 9:03 AM, Kadir Cetinkaya via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Author: kadircet<br class="">Date: Thu Jan 10 09:03:04 2019<br class="">New Revision: 350847<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=350847&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=350847&view=rev</a><br class="">Log:<br class="">[clangd] Introduce loading of shards within auto-index<br class=""><br class="">Summary:<br class="">Whenever a change happens on a CDB, load shards associated with that<br class="">CDB before issuing re-index actions.<br class=""><br class="">Reviewers: ilya-biryukov<br class=""><br class="">Reviewed By: ilya-biryukov<br class=""><br class="">Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits<br class=""><br class="">Differential Revision: <a href="https://reviews.llvm.org/D55224" class="">https://reviews.llvm.org/D55224</a><br class=""><br class="">Modified:<br class="">    clang-tools-extra/trunk/clangd/index/Background.cpp<br class="">    clang-tools-extra/trunk/clangd/index/Background.h<br class="">    clang-tools-extra/trunk/test/clangd/background-index.test<br class="">    clang-tools-extra/trunk/unittests/clangd/BackgroundIndexTests.cpp<br class=""><br class="">Modified: clang-tools-extra/trunk/clangd/index/Background.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Background.cpp?rev=350847&r1=350846&r2=350847&view=diff" class="">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Background.cpp?rev=350847&r1=350846&r2=350847&view=diff</a><br class="">==============================================================================<br class="">--- clang-tools-extra/trunk/clangd/index/Background.cpp (original)<br class="">+++ clang-tools-extra/trunk/clangd/index/Background.cpp Thu Jan 10 09:03:04 2019<br class="">@@ -115,6 +115,19 @@ createFileFilter(const llvm::StringMap<F<br class="">   };<br class=""> }<br class=""><br class="">+// We cannot use vfs->makeAbsolute because Cmd.FileName is either absolute or<br class="">+// relative to Cmd.Directory, which might not be the same as current working<br class="">+// directory.<br class="">+llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {<br class="">+  llvm::SmallString<128> AbsolutePath;<br class="">+  if (llvm::sys::path::is_absolute(Cmd.Filename)) {<br class="">+    AbsolutePath = Cmd.Filename;<br class="">+  } else {<br class="">+    AbsolutePath = Cmd.Directory;<br class="">+    llvm::sys::path::append(AbsolutePath, Cmd.Filename);<br class="">+  }<br class="">+  return AbsolutePath;<br class="">+}<br class=""> } // namespace<br class=""><br class=""> BackgroundIndex::BackgroundIndex(<br class="">@@ -204,40 +217,33 @@ void BackgroundIndex::enqueue(const std:<br class="">       [this, ChangedFiles] {<br class="">         trace::Span Tracer("BackgroundIndexEnqueue");<br class="">         // We're doing this asynchronously, because we'll read shards here too.<br class="">-        // FIXME: read shards here too.<br class="">-<br class="">         log("Enqueueing {0} commands for indexing", ChangedFiles.size());<br class="">         SPAN_ATTACH(Tracer, "files", int64_t(ChangedFiles.size()));<br class=""><br class="">-        // We shuffle the files because processing them in a random order should<br class="">-        // quickly give us good coverage of headers in the project.<br class="">-        std::vector<unsigned> Permutation(ChangedFiles.size());<br class="">-        std::iota(Permutation.begin(), Permutation.end(), 0);<br class="">-        std::mt19937 Generator(std::random_device{}());<br class="">-        std::shuffle(Permutation.begin(), Permutation.end(), Generator);<br class="">-<br class="">-        for (const unsigned I : Permutation)<br class="">-          enqueue(ChangedFiles[I]);<br class="">+        auto NeedsReIndexing = loadShards(std::move(ChangedFiles));<br class="">+        // Run indexing for files that need to be updated.<br class="">+        std::shuffle(NeedsReIndexing.begin(), NeedsReIndexing.end(),<br class="">+                     std::mt19937(std::random_device{}()));<br class="">+        for (auto &Elem : NeedsReIndexing)<br class="">+          enqueue(std::move(Elem.first), Elem.second);<br class="">       },<br class="">       ThreadPriority::Normal);<br class=""> }<br class=""><br class="">-void BackgroundIndex::enqueue(const std::string &File) {<br class="">-  ProjectInfo Project;<br class="">-  if (auto Cmd = CDB.getCompileCommand(File, &Project)) {<br class="">-    auto *Storage = IndexStorageFactory(Project.SourceRoot);<br class="">-    // Set priority to low, since background indexing is a long running<br class="">-    // task we do not want to eat up cpu when there are any other high<br class="">-    // priority threads.<br class="">-    enqueueTask(Bind(<br class="">-                    [this, File, Storage](tooling::CompileCommand Cmd) {<br class="">-                      Cmd.CommandLine.push_back("-resource-dir=" + ResourceDir);<br class="">-                      if (auto Error = index(std::move(Cmd), Storage))<br class="">-                        log("Indexing {0} failed: {1}", File, std::move(Error));<br class="">-                    },<br class="">-                    std::move(*Cmd)),<br class="">-                ThreadPriority::Low);<br class="">-  }<br class="">+void BackgroundIndex::enqueue(tooling::CompileCommand Cmd,<br class="">+                              BackgroundIndexStorage *Storage) {<br class="">+  enqueueTask(Bind(<br class="">+                  [this, Storage](tooling::CompileCommand Cmd) {<br class="">+                    Cmd.CommandLine.push_back("-resource-dir=" + ResourceDir);<br class="">+                    // We can't use llvm::StringRef here since we are going to<br class="">+                    // move from Cmd during the call below.<br class="">+                    const std::string FileName = Cmd.Filename;<br class="">+                    if (auto Error = index(std::move(Cmd), Storage))<br class="">+                      elog("Indexing {0} failed: {1}", FileName,<br class="">+                           std::move(Error));<br class="">+                  },<br class="">+                  std::move(Cmd)),<br class="">+              ThreadPriority::Low);<br class=""> }<br class=""><br class=""> void BackgroundIndex::enqueueTask(Task T, ThreadPriority Priority) {<br class="">@@ -299,22 +305,22 @@ void BackgroundIndex::update(llvm::Strin<br class="">   }<br class=""><br class="">   // Build and store new slabs for each updated file.<br class="">-  for (const auto &F : Files) {<br class="">-    llvm::StringRef Path = F.first();<br class="">-    vlog("Update symbols in {0}", Path);<br class="">+  for (const auto &I : *Index.Sources) {<br class="">+    std::string Path = URICache.resolve(I.first());<br class="">     SymbolSlab::Builder Syms;<br class="">     RefSlab::Builder Refs;<br class="">-    for (const auto *S : F.second.Symbols)<br class="">-      Syms.insert(*S);<br class="">-    for (const auto *R : F.second.Refs)<br class="">-      Refs.insert(RefToIDs[R], *R);<br class="">-<br class="">+    auto FileIt = Files.find(Path);<br class="">+    if (FileIt != Files.end()) {<br class="">+      auto &F = *FileIt;<br class="">+      for (const auto *S : F.second.Symbols)<br class="">+        Syms.insert(*S);<br class="">+      for (const auto *R : F.second.Refs)<br class="">+        Refs.insert(RefToIDs[R], *R);<br class="">+    }<br class="">     auto SS = llvm::make_unique<SymbolSlab>(std::move(Syms).build());<br class="">     auto RS = llvm::make_unique<RefSlab>(std::move(Refs).build());<br class="">     auto IG = llvm::make_unique<IncludeGraph>(<br class="">         getSubGraph(URI::create(Path), Index.Sources.getValue()));<br class="">-<br class="">-    auto Hash = FilesToUpdate.lookup(Path);<br class="">     // We need to store shards before updating the index, since the latter<br class="">     // consumes slabs.<br class="">     if (IndexStorage) {<br class="">@@ -327,13 +333,19 @@ void BackgroundIndex::update(llvm::Strin<br class="">         elog("Failed to write background-index shard for file {0}: {1}", Path,<br class="">              std::move(Error));<br class="">     }<br class="">-<br class="">-    std::lock_guard<std::mutex> Lock(DigestsMu);<br class="">-    // This can override a newer version that is added in another thread,<br class="">-    // if this thread sees the older version but finishes later. This should be<br class="">-    // rare in practice.<br class="">-    IndexedFileDigests[Path] = Hash;<br class="">-    IndexedSymbols.update(Path, std::move(SS), std::move(RS));<br class="">+    {<br class="">+      std::lock_guard<std::mutex> Lock(DigestsMu);<br class="">+      auto Hash = I.second.Digest;<br class="">+      // Skip if file is already up to date.<br class="">+      auto DigestIt = IndexedFileDigests.try_emplace(Path);<br class="">+      if (!DigestIt.second && DigestIt.first->second == Hash)<br class="">+        continue;<br class="">+      DigestIt.first->second = Hash;<br class="">+      // This can override a newer version that is added in another thread, if<br class="">+      // this thread sees the older version but finishes later. This should be<br class="">+      // rare in practice.<br class="">+      IndexedSymbols.update(Path, std::move(SS), std::move(RS));<br class="">+    }<br class="">   }<br class=""> }<br class=""><br class="">@@ -342,11 +354,11 @@ void BackgroundIndex::buildIndex() {<br class="">   while (true) {<br class="">     {<br class="">       std::unique_lock<std::mutex> Lock(IndexMu);<br class="">-      if (ShouldStop)  // Avoid waiting if stopped.<br class="">+      if (ShouldStop) // Avoid waiting if stopped.<br class="">         break;<br class="">       // Wait until this is notified to stop or `BuildIndexPeriodMs` has past.<br class="">       IndexCV.wait_for(Lock, std::chrono::milliseconds(BuildIndexPeriodMs));<br class="">-      if (ShouldStop)  // Avoid rebuilding index if stopped.<br class="">+      if (ShouldStop) // Avoid rebuilding index if stopped.<br class="">         break;<br class="">     }<br class="">     if (!SymbolsUpdatedSinceLastIndex.exchange(false))<br class="">@@ -365,13 +377,7 @@ llvm::Error BackgroundIndex::index(tooli<br class="">                                    BackgroundIndexStorage *IndexStorage) {<br class="">   trace::Span Tracer("BackgroundIndex");<br class="">   SPAN_ATTACH(Tracer, "file", Cmd.Filename);<br class="">-  llvm::SmallString<128> AbsolutePath;<br class="">-  if (llvm::sys::path::is_absolute(Cmd.Filename)) {<br class="">-    AbsolutePath = Cmd.Filename;<br class="">-  } else {<br class="">-    AbsolutePath = Cmd.Directory;<br class="">-    llvm::sys::path::append(AbsolutePath, Cmd.Filename);<br class="">-  }<br class="">+  auto AbsolutePath = getAbsolutePath(Cmd);<br class=""><br class="">   auto FS = FSProvider.getFileSystem();<br class="">   auto Buf = FS->getBufferForFile(AbsolutePath);<br class="">@@ -383,11 +389,6 @@ llvm::Error BackgroundIndex::index(tooli<br class="">   llvm::StringMap<FileDigest> DigestsSnapshot;<br class="">   {<br class="">     std::lock_guard<std::mutex> Lock(DigestsMu);<br class="">-    if (IndexedFileDigests.lookup(AbsolutePath) == Hash) {<br class="">-      vlog("No need to index {0}, already up to date", AbsolutePath);<br class="">-      return llvm::Error::success();<br class="">-    }<br class="">-<br class="">     DigestsSnapshot = IndexedFileDigests;<br class="">   }<br class=""><br class="">@@ -437,8 +438,8 @@ llvm::Error BackgroundIndex::index(tooli<br class="">         "IndexingAction failed: has uncompilable errors");<br class="">   }<br class=""><br class="">-  assert(Index.Symbols && Index.Refs && Index.Sources<br class="">-     && "Symbols, Refs and Sources must be set.");<br class="">+  assert(Index.Symbols && Index.Refs && Index.Sources &&<br class="">+         "Symbols, Refs and Sources must be set.");<br class=""><br class="">   log("Indexed {0} ({1} symbols, {2} refs, {3} files)",<br class="">       Inputs.CompileCommand.Filename, Index.Symbols->size(),<br class="">@@ -448,12 +449,6 @@ llvm::Error BackgroundIndex::index(tooli<br class="">   SPAN_ATTACH(Tracer, "sources", int(Index.Sources->size()));<br class=""><br class="">   update(AbsolutePath, std::move(Index), FilesToUpdate, IndexStorage);<br class="">-  {<br class="">-    // Make sure hash for the main file is always updated even if there is no<br class="">-    // index data in it.<br class="">-    std::lock_guard<std::mutex> Lock(DigestsMu);<br class="">-    IndexedFileDigests[AbsolutePath] = Hash;<br class="">-  }<br class=""><br class="">   if (BuildIndexPeriodMs > 0)<br class="">     SymbolsUpdatedSinceLastIndex = true;<br class="">@@ -464,5 +459,146 @@ llvm::Error BackgroundIndex::index(tooli<br class="">   return llvm::Error::success();<br class=""> }<br class=""><br class="">+std::vector<BackgroundIndex::Source><br class="">+BackgroundIndex::loadShard(const tooling::CompileCommand &Cmd,<br class="">+                           BackgroundIndexStorage *IndexStorage,<br class="">+                           llvm::StringSet<> &LoadedShards) {<br class="">+  struct ShardInfo {<br class="">+    std::string AbsolutePath;<br class="">+    std::unique_ptr<IndexFileIn> Shard;<br class="">+    FileDigest Digest;<br class="">+  };<br class="">+  std::vector<ShardInfo> IntermediateSymbols;<br class="">+  // Make sure we don't have duplicate elements in the queue. Keys are absolute<br class="">+  // paths.<br class="">+  llvm::StringSet<> InQueue;<br class="">+  auto FS = FSProvider.getFileSystem();<br class="">+  // Dependencies of this TU, paired with the information about whether they<br class="">+  // need to be re-indexed or not.<br class="">+  std::vector<Source> Dependencies;<br class="">+  std::string AbsolutePath = getAbsolutePath(Cmd).str();<br class="">+  // Up until we load the shard related to a dependency it needs to be<br class="">+  // re-indexed.<br class="">+  Dependencies.emplace_back(AbsolutePath, true);<br class="">+  InQueue.insert(AbsolutePath);<br class="">+  // Goes over each dependency.<br class="">+  for (size_t CurrentDependency = 0; CurrentDependency < Dependencies.size();<br class="">+       CurrentDependency++) {<br class="">+    llvm::StringRef CurDependencyPath = Dependencies[CurrentDependency].Path;<br class="">+    // If we have already seen this shard before(either loaded or failed) don't<br class="">+    // re-try again. Since the information in the shard won't change from one TU<br class="">+    // to another.<br class="">+    if (!LoadedShards.try_emplace(CurDependencyPath).second) {<br class="">+      // If the dependency needs to be re-indexed, first occurence would already<br class="">+      // have detected that, so we don't need to issue it again.<br class="">+      Dependencies[CurrentDependency].NeedsReIndexing = false;<br class="">+      continue;<br class="">+    }<br class="">+<br class="">+    auto Shard = IndexStorage->loadShard(CurDependencyPath);<br class="">+    if (!Shard || !Shard->Sources) {<br class="">+      // File will be returned as requiring re-indexing to caller.<br class="">+      vlog("Failed to load shard: {0}", CurDependencyPath);<br class="">+      continue;<br class="">+    }<br class="">+    // These are the edges in the include graph for current dependency.<br class="">+    for (const auto &I : *Shard->Sources) {<br class="">+      auto U = URI::parse(I.getKey());<br class="">+      if (!U)<br class="">+        continue;<br class="">+      auto AbsolutePath = URI::resolve(*U, CurDependencyPath);<br class="">+      if (!AbsolutePath)<br class="">+        continue;<br class="">+      // Add file as dependency if haven't seen before.<br class="">+      if (InQueue.try_emplace(*AbsolutePath).second)<br class="">+        Dependencies.emplace_back(*AbsolutePath, true);<br class="">+      // The node contains symbol information only for current file, the rest is<br class="">+      // just edges.<br class="">+      if (*AbsolutePath != CurDependencyPath)<br class="">+        continue;<br class="">+<br class="">+      // We found source file info for current dependency.<br class="">+      assert(I.getValue().Digest != FileDigest{{0}} && "Digest is empty?");<br class="">+      ShardInfo SI;<br class="">+      SI.AbsolutePath = CurDependencyPath;<br class="">+      SI.Shard = std::move(Shard);<br class="">+      SI.Digest = I.getValue().Digest;<br class="">+      IntermediateSymbols.push_back(std::move(SI));<br class="">+      // Check if the source needs re-indexing.<br class="">+      // Get the digest, skip it if file doesn't exist.<br class="">+      auto Buf = FS->getBufferForFile(CurDependencyPath);<br class="">+      if (!Buf) {<br class="">+        elog("Couldn't get buffer for file: {0}: {1}", CurDependencyPath,<br class="">+             Buf.getError().message());<br class="">+        continue;<br class="">+      }<br class="">+      // If digests match then dependency doesn't need re-indexing.<br class="">+      Dependencies[CurrentDependency].NeedsReIndexing =<br class="">+          digest(Buf->get()->getBuffer()) != I.getValue().Digest;<br class="">+    }<br class="">+  }<br class="">+  // Load shard information into background-index.<br class="">+  {<br class="">+    std::lock_guard<std::mutex> Lock(DigestsMu);<br class="">+    // This can override a newer version that is added in another thread,<br class="">+    // if this thread sees the older version but finishes later. This<br class="">+    // should be rare in practice.<br class="">+    for (const ShardInfo &SI : IntermediateSymbols) {<br class="">+      auto SS =<br class="">+          SI.Shard->Symbols<br class="">+              ? llvm::make_unique<SymbolSlab>(std::move(*SI.Shard->Symbols))<br class="">+              : nullptr;<br class="">+      auto RS = SI.Shard->Refs<br class="">+                    ? llvm::make_unique<RefSlab>(std::move(*SI.Shard->Refs))<br class="">+                    : nullptr;<br class="">+      IndexedFileDigests[SI.AbsolutePath] = SI.Digest;<br class="">+      IndexedSymbols.update(SI.AbsolutePath, std::move(SS), std::move(RS));<br class="">+    }<br class="">+  }<br class="">+<br class="">+  return Dependencies;<br class="">+}<br class="">+<br class="">+// Goes over each changed file and loads them from index. Returns the list of<br class="">+// TUs that had out-of-date/no shards.<br class="">+std::vector<std::pair<tooling::CompileCommand, BackgroundIndexStorage *>><br class="">+BackgroundIndex::loadShards(std::vector<std::string> ChangedFiles) {<br class="">+  std::vector<std::pair<tooling::CompileCommand, BackgroundIndexStorage *>><br class="">+      NeedsReIndexing;<br class="">+  // Keeps track of the files that will be reindexed, to make sure we won't<br class="">+  // re-index same dependencies more than once. Keys are AbsolutePaths.<br class="">+  llvm::StringSet<> FilesToIndex;<br class="">+  // Keeps track of the loaded shards to make sure we don't perform redundant<br class="">+  // disk IO. Keys are absolute paths.<br class="">+  llvm::StringSet<> LoadedShards;<br class="">+  for (const auto &File : ChangedFiles) {<br class="">+    ProjectInfo PI;<br class="">+    auto Cmd = CDB.getCompileCommand(File, &PI);<br class="">+    if (!Cmd)<br class="">+      continue;<br class="">+    BackgroundIndexStorage *IndexStorage = IndexStorageFactory(PI.SourceRoot);<br class="">+    auto Dependencies = loadShard(*Cmd, IndexStorage, LoadedShards);<br class="">+    for (const auto &Dependency : Dependencies) {<br class="">+      if (!Dependency.NeedsReIndexing || FilesToIndex.count(Dependency.Path))<br class="">+        continue;<br class="">+      // FIXME: Currently, we simply schedule indexing on a TU whenever any of<br class="">+      // its dependencies needs re-indexing. We might do it smarter by figuring<br class="">+      // out a minimal set of TUs that will cover all the stale dependencies.<br class="">+      vlog("Enqueueing TU {0} because its dependency {1} needs re-indexing.",<br class="">+           Cmd->Filename, Dependency.Path);<br class="">+      NeedsReIndexing.push_back({std::move(*Cmd), IndexStorage});<br class="">+      // Mark all of this TU's dependencies as to-be-indexed so that we won't<br class="">+      // try to re-index those.<br class="">+      for (const auto &Dependency : Dependencies)<br class="">+        FilesToIndex.insert(Dependency.Path);<br class="">+      break;<br class="">+    }<br class="">+  }<br class="">+  vlog("Loaded all shards");<br class="">+  reset(IndexedSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge));<br class="">+<br class="">+  return NeedsReIndexing;<br class="">+}<br class="">+<br class=""> } // namespace clangd<br class=""> } // namespace clang<br class=""><br class="">Modified: clang-tools-extra/trunk/clangd/index/Background.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Background.h?rev=350847&r1=350846&r2=350847&view=diff" class="">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Background.h?rev=350847&r1=350846&r2=350847&view=diff</a><br class="">==============================================================================<br class="">--- clang-tools-extra/trunk/clangd/index/Background.h (original)<br class="">+++ clang-tools-extra/trunk/clangd/index/Background.h Thu Jan 10 09:03:04 2019<br class="">@@ -81,7 +81,6 @@ public:<br class="">   // The indexing happens in a background thread, so the symbols will be<br class="">   // available sometime later.<br class="">   void enqueue(const std::vector<std::string> &ChangedFiles);<br class="">-  void enqueue(const std::string &File);<br class=""><br class="">   // Cause background threads to stop after ther current task, any remaining<br class="">   // tasks will be discarded.<br class="">@@ -118,6 +117,21 @@ private:<br class="">   std::mutex DigestsMu;<br class=""><br class="">   BackgroundIndexStorage::Factory IndexStorageFactory;<br class="">+  struct Source {<br class="">+    std::string Path;<br class="">+    bool NeedsReIndexing;<br class="">+    Source(llvm::StringRef Path, bool NeedsReIndexing)<br class="">+        : Path(Path), NeedsReIndexing(NeedsReIndexing) {}<br class="">+  };<br class="">+  // Loads the shards for a single TU and all of its dependencies. Returns the<br class="">+  // list of sources and whether they need to be re-indexed.<br class="">+  std::vector<Source> loadShard(const tooling::CompileCommand &Cmd,<br class="">+                                BackgroundIndexStorage *IndexStorage,<br class="">+                                llvm::StringSet<> &LoadedShards);<br class="">+  // Tries to load shards for the ChangedFiles.<br class="">+  std::vector<std::pair<tooling::CompileCommand, BackgroundIndexStorage *>><br class="">+  loadShards(std::vector<std::string> ChangedFiles);<br class="">+  void enqueue(tooling::CompileCommand Cmd, BackgroundIndexStorage *Storage);<br class=""><br class="">   // queue management<br class="">   using Task = std::function<void()>;<br class=""><br class="">Modified: clang-tools-extra/trunk/test/clangd/background-index.test<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/background-index.test?rev=350847&r1=350846&r2=350847&view=diff" class="">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/background-index.test?rev=350847&r1=350846&r2=350847&view=diff</a><br class="">==============================================================================<br class="">--- clang-tools-extra/trunk/test/clangd/background-index.test (original)<br class="">+++ clang-tools-extra/trunk/test/clangd/background-index.test Thu Jan 10 09:03:04 2019<br class="">@@ -16,6 +16,5 @@<br class=""> # RUN: ls %t/.clangd-index/foo.cpp.*.idx<br class=""><br class=""> # Test the index is read from disk: delete code and restart clangd.<br class="">-# FIXME: This test currently fails as we don't read the index yet.<br class=""> # RUN: rm %t/foo.cpp<br class="">-# RUN: clangd -background-index -lit-test < %t/definition.jsonrpc | not FileCheck %t/definition.jsonrpc<br class="">+# RUN: clangd -background-index -lit-test < %t/definition.jsonrpc | FileCheck %t/definition.jsonrpc<br class=""><br class="">Modified: clang-tools-extra/trunk/unittests/clangd/BackgroundIndexTests.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/BackgroundIndexTests.cpp?rev=350847&r1=350846&r2=350847&view=diff" class="">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/BackgroundIndexTests.cpp?rev=350847&r1=350846&r2=350847&view=diff</a><br class="">==============================================================================<br class="">--- clang-tools-extra/trunk/unittests/clangd/BackgroundIndexTests.cpp (original)<br class="">+++ clang-tools-extra/trunk/unittests/clangd/BackgroundIndexTests.cpp Thu Jan 10 09:03:04 2019<br class="">@@ -9,6 +9,7 @@<br class=""><br class=""> using testing::_;<br class=""> using testing::AllOf;<br class="">+using testing::Contains;<br class=""> using testing::ElementsAre;<br class=""> using testing::Not;<br class=""> using testing::UnorderedElementsAre;<br class="">@@ -146,7 +147,7 @@ TEST_F(BackgroundIndexTest, IndexTwoFile<br class="">                        FileURI("<a href="unittest:///root/B.cc" class="">unittest:///root/B.cc</a>")}));<br class=""> }<br class=""><br class="">-TEST_F(BackgroundIndexTest, ShardStorageWriteTest) {<br class="">+TEST_F(BackgroundIndexTest, ShardStorageTest) {<br class="">   MockFSProvider FS;<br class="">   FS.Files[testPath("root/A.h")] = R"cpp(<br class="">       void common();<br class="">@@ -175,6 +176,16 @@ TEST_F(BackgroundIndexTest, ShardStorage<br class="">   EXPECT_EQ(CacheHits, 0U);<br class="">   EXPECT_EQ(Storage.size(), 2U);<br class=""><br class="">+  {<br class="">+    OverlayCDB CDB(/*Base=*/nullptr);<br class="">+    BackgroundIndex Idx(Context::empty(), "", FS, CDB,<br class="">+                        [&](llvm::StringRef) { return &MSS; });<br class="">+    CDB.setCompileCommand(testPath("root"), Cmd);<br class="">+    ASSERT_TRUE(Idx.blockUntilIdleForTest());<br class="">+  }<br class="">+  EXPECT_EQ(CacheHits, 2U); // Check both <a href="http://A.cc" class="">A.cc</a> and A.h loaded from cache.<br class="">+  EXPECT_EQ(Storage.size(), 2U);<br class="">+<br class="">   auto ShardHeader = MSS.loadShard(testPath("root/A.h"));<br class="">   EXPECT_NE(ShardHeader, nullptr);<br class="">   EXPECT_THAT(<br class="">@@ -278,5 +289,73 @@ TEST_F(BackgroundIndexTest, DISABLED_Per<br class="">   EXPECT_THAT(runFuzzyFind(Idx, ""), ElementsAre(Named("Y")));<br class=""> }<br class=""><br class="">+TEST_F(BackgroundIndexTest, ShardStorageLoad) {<br class="">+  MockFSProvider FS;<br class="">+  FS.Files[testPath("root/A.h")] = R"cpp(<br class="">+      void common();<br class="">+      void f_b();<br class="">+      class A_CC {};<br class="">+      )cpp";<br class="">+  FS.Files[testPath("root/<a href="http://A.cc" class="">A.cc</a>")] =<br class="">+      "#include \"A.h\"\nvoid g() { (void)common; }";<br class="">+<br class="">+  llvm::StringMap<std::string> Storage;<br class="">+  size_t CacheHits = 0;<br class="">+  MemoryShardStorage MSS(Storage, CacheHits);<br class="">+<br class="">+  tooling::CompileCommand Cmd;<br class="">+  Cmd.Filename = testPath("root/<a href="http://A.cc" class="">A.cc</a>");<br class="">+  Cmd.Directory = testPath("root");<br class="">+  Cmd.CommandLine = {"clang++", testPath("root/<a href="http://A.cc" class="">A.cc</a>")};<br class="">+  // Check nothing is loaded from Storage, but <a href="http://A.cc" class="">A.cc</a> and A.h has been stored.<br class="">+  {<br class="">+    OverlayCDB CDB(/*Base=*/nullptr);<br class="">+    BackgroundIndex Idx(Context::empty(), "", FS, CDB,<br class="">+                        [&](llvm::StringRef) { return &MSS; });<br class="">+    CDB.setCompileCommand(testPath("root/<a href="http://A.cc" class="">A.cc</a>"), Cmd);<br class="">+    ASSERT_TRUE(Idx.blockUntilIdleForTest());<br class="">+  }<br class="">+<br class="">+  // Change header.<br class="">+  FS.Files[testPath("root/A.h")] = R"cpp(<br class="">+      void common();<br class="">+      void f_b();<br class="">+      class A_CC {};<br class="">+      class A_CCnew {};<br class="">+      )cpp";<br class="">+  {<br class="">+    OverlayCDB CDB(/*Base=*/nullptr);<br class="">+    BackgroundIndex Idx(Context::empty(), "", FS, CDB,<br class="">+                        [&](llvm::StringRef) { return &MSS; });<br class="">+    CDB.setCompileCommand(testPath("root"), Cmd);<br class="">+    ASSERT_TRUE(Idx.blockUntilIdleForTest());<br class="">+  }<br class="">+  EXPECT_EQ(CacheHits, 2U); // Check both <a href="http://A.cc" class="">A.cc</a> and A.h loaded from cache.<br class="">+<br class="">+  // Check if the new symbol has arrived.<br class="">+  auto ShardHeader = MSS.loadShard(testPath("root/A.h"));<br class="">+  EXPECT_NE(ShardHeader, nullptr);<br class="">+  EXPECT_THAT(*ShardHeader->Symbols, Contains(Named("A_CCnew")));<br class="">+<br class="">+  // Change source.<br class="">+  FS.Files[testPath("root/<a href="http://A.cc" class="">A.cc</a>")] =<br class="">+      "#include \"A.h\"\nvoid g() { (void)common; }\nvoid f_b() {}";<br class="">+  {<br class="">+    CacheHits = 0;<br class="">+    OverlayCDB CDB(/*Base=*/nullptr);<br class="">+    BackgroundIndex Idx(Context::empty(), "", FS, CDB,<br class="">+                        [&](llvm::StringRef) { return &MSS; });<br class="">+    CDB.setCompileCommand(testPath("root"), Cmd);<br class="">+    ASSERT_TRUE(Idx.blockUntilIdleForTest());<br class="">+  }<br class="">+  EXPECT_EQ(CacheHits, 2U); // Check both <a href="http://A.cc" class="">A.cc</a> and A.h loaded from cache.<br class="">+<br class="">+  // Check if the new symbol has arrived.<br class="">+  auto ShardSource = MSS.loadShard(testPath("root/<a href="http://A.cc" class="">A.cc</a>"));<br class="">+  EXPECT_NE(ShardHeader, nullptr);<br class="">+  EXPECT_THAT(*ShardSource->Symbols,<br class="">+              Contains(AllOf(Named("f_b"), Declared(), Defined())));<br class="">+}<br class="">+<br class=""> } // namespace clangd<br class=""> } // namespace clang<br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits<br class=""></div></div></blockquote></div><br class=""></div></div></body></html>