<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>