[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
//===-- Background.cpp - Build an index in a background thread ------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "index/Background.h"
|
|
|
|
#include "Compiler.h"
|
2020-07-14 21:17:16 +08:00
|
|
|
#include "Config.h"
|
2019-07-04 17:51:43 +08:00
|
|
|
#include "Headers.h"
|
2019-09-04 17:46:06 +08:00
|
|
|
#include "ParsedAST.h"
|
2018-11-28 00:08:53 +08:00
|
|
|
#include "SourceCode.h"
|
2019-02-28 21:23:03 +08:00
|
|
|
#include "Symbol.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "URI.h"
|
2019-07-19 18:18:52 +08:00
|
|
|
#include "index/BackgroundIndexLoader.h"
|
[clangd] Rewrite of logic to rebuild the background index serving structures.
Summary:
Previously it was rebuilding every 5s by default, which was much too frequent
in the long run - the goal was to provide an early build. There were also some
bugs. There were also some bugs, and a dedicated thread was used in production
but not tested.
- rebuilds are triggered by #TUs built, rather than time. This should scale
more sensibly to fast vs slow machines.
- there are two separate indexed-TU thresholds to trigger index build: 5 TUs
for the first build, 100 for subsequent rebuilds.
- rebuild is always done on the regular indexing threads, and is affected by
blockUntilIdle. This means unit/lit tests run the production configuration.
- fixed a bug where we'd rebuild after attempting to load shards, even if there
were no shards.
- the BackgroundIndexTests don't really test the subtleties of the rebuild
policy (for determinism, we call blockUntilIdle, so rebuild-on-idle is enough
to pass the tests). Instead, we expose the rebuilder as a separate class and
have fine-grained tests for it.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64291
llvm-svn: 365531
2019-07-10 02:30:49 +08:00
|
|
|
#include "index/FileIndex.h"
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
#include "index/IndexAction.h"
|
|
|
|
#include "index/MemIndex.h"
|
2019-07-04 17:51:43 +08:00
|
|
|
#include "index/Ref.h"
|
|
|
|
#include "index/Relation.h"
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
#include "index/Serialization.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "index/SymbolCollector.h"
|
[clangd] Move non-clang base pieces into separate support/ lib. NFCI
Summary:
This enforces layering, reduces a sprawling clangd/ directory, and makes life
easier for embedders.
Reviewers: kbobyrev
Subscribers: mgorny, ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, jfb, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D79014
2020-04-28 23:49:17 +08:00
|
|
|
#include "support/Context.h"
|
|
|
|
#include "support/Logger.h"
|
|
|
|
#include "support/Path.h"
|
|
|
|
#include "support/Threading.h"
|
2020-06-17 17:53:32 +08:00
|
|
|
#include "support/ThreadsafeFS.h"
|
[clangd] Move non-clang base pieces into separate support/ lib. NFCI
Summary:
This enforces layering, reduces a sprawling clangd/ directory, and makes life
easier for embedders.
Reviewers: kbobyrev
Subscribers: mgorny, ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, jfb, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D79014
2020-04-28 23:49:17 +08:00
|
|
|
#include "support/Trace.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "clang/Basic/SourceLocation.h"
|
|
|
|
#include "clang/Basic/SourceManager.h"
|
2019-07-12 18:18:42 +08:00
|
|
|
#include "clang/Driver/Types.h"
|
2019-07-19 18:18:52 +08:00
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
|
|
#include "llvm/ADT/DenseSet.h"
|
2019-07-04 17:51:53 +08:00
|
|
|
#include "llvm/ADT/Hashing.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2018-12-17 20:30:27 +08:00
|
|
|
#include "llvm/ADT/ScopeExit.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
2019-07-04 17:51:43 +08:00
|
|
|
#include "llvm/ADT/StringSet.h"
|
|
|
|
#include "llvm/Support/Error.h"
|
2019-07-11 21:34:38 +08:00
|
|
|
#include "llvm/Support/Path.h"
|
2019-04-18 21:46:40 +08:00
|
|
|
#include "llvm/Support/Threading.h"
|
2018-11-16 17:03:56 +08:00
|
|
|
|
2019-07-11 21:34:38 +08:00
|
|
|
#include <algorithm>
|
2019-04-18 21:46:40 +08:00
|
|
|
#include <atomic>
|
2018-12-18 23:39:33 +08:00
|
|
|
#include <chrono>
|
[clangd] Rewrite of logic to rebuild the background index serving structures.
Summary:
Previously it was rebuilding every 5s by default, which was much too frequent
in the long run - the goal was to provide an early build. There were also some
bugs. There were also some bugs, and a dedicated thread was used in production
but not tested.
- rebuilds are triggered by #TUs built, rather than time. This should scale
more sensibly to fast vs slow machines.
- there are two separate indexed-TU thresholds to trigger index build: 5 TUs
for the first build, 100 for subsequent rebuilds.
- rebuild is always done on the regular indexing threads, and is affected by
blockUntilIdle. This means unit/lit tests run the production configuration.
- fixed a bug where we'd rebuild after attempting to load shards, even if there
were no shards.
- the BackgroundIndexTests don't really test the subtleties of the rebuild
policy (for determinism, we call blockUntilIdle, so rebuild-on-idle is enough
to pass the tests). Instead, we expose the rebuilder as a separate class and
have fine-grained tests for it.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64291
llvm-svn: 365531
2019-07-10 02:30:49 +08:00
|
|
|
#include <condition_variable>
|
2019-07-19 18:18:52 +08:00
|
|
|
#include <cstddef>
|
2018-11-16 17:03:56 +08:00
|
|
|
#include <memory>
|
[clangd] Rewrite of logic to rebuild the background index serving structures.
Summary:
Previously it was rebuilding every 5s by default, which was much too frequent
in the long run - the goal was to provide an early build. There were also some
bugs. There were also some bugs, and a dedicated thread was used in production
but not tested.
- rebuilds are triggered by #TUs built, rather than time. This should scale
more sensibly to fast vs slow machines.
- there are two separate indexed-TU thresholds to trigger index build: 5 TUs
for the first build, 100 for subsequent rebuilds.
- rebuild is always done on the regular indexing threads, and is affected by
blockUntilIdle. This means unit/lit tests run the production configuration.
- fixed a bug where we'd rebuild after attempting to load shards, even if there
were no shards.
- the BackgroundIndexTests don't really test the subtleties of the rebuild
policy (for determinism, we call blockUntilIdle, so rebuild-on-idle is enough
to pass the tests). Instead, we expose the rebuilder as a separate class and
have fine-grained tests for it.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64291
llvm-svn: 365531
2019-07-10 02:30:49 +08:00
|
|
|
#include <mutex>
|
2018-11-26 21:35:02 +08:00
|
|
|
#include <numeric>
|
2018-11-16 17:03:56 +08:00
|
|
|
#include <queue>
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
#include <random>
|
2018-11-06 18:55:21 +08:00
|
|
|
#include <string>
|
2018-12-18 23:39:33 +08:00
|
|
|
#include <thread>
|
2019-07-19 18:18:52 +08:00
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
2018-12-04 19:31:57 +08:00
|
|
|
namespace {
|
2019-04-18 21:46:40 +08:00
|
|
|
|
2019-01-11 01:03:04 +08:00
|
|
|
// We cannot use vfs->makeAbsolute because Cmd.FileName is either absolute or
|
|
|
|
// relative to Cmd.Directory, which might not be the same as current working
|
|
|
|
// directory.
|
|
|
|
llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {
|
|
|
|
llvm::SmallString<128> AbsolutePath;
|
|
|
|
if (llvm::sys::path::is_absolute(Cmd.Filename)) {
|
|
|
|
AbsolutePath = Cmd.Filename;
|
|
|
|
} else {
|
|
|
|
AbsolutePath = Cmd.Directory;
|
|
|
|
llvm::sys::path::append(AbsolutePath, Cmd.Filename);
|
2019-03-08 17:57:33 +08:00
|
|
|
llvm::sys::path::remove_dots(AbsolutePath, true);
|
2019-01-11 01:03:04 +08:00
|
|
|
}
|
|
|
|
return AbsolutePath;
|
|
|
|
}
|
2019-07-19 18:18:52 +08:00
|
|
|
|
|
|
|
bool shardIsStale(const LoadedShard &LS, llvm::vfs::FileSystem *FS) {
|
|
|
|
auto Buf = FS->getBufferForFile(LS.AbsolutePath);
|
|
|
|
if (!Buf) {
|
|
|
|
elog("Background-index: Couldn't read {0} to validate stored index: {1}",
|
|
|
|
LS.AbsolutePath, Buf.getError().message());
|
|
|
|
// There is no point in indexing an unreadable file.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return digest(Buf->get()->getBuffer()) != LS.Digest;
|
|
|
|
}
|
|
|
|
|
2018-12-04 19:31:57 +08:00
|
|
|
} // namespace
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
2018-11-16 17:03:56 +08:00
|
|
|
BackgroundIndex::BackgroundIndex(
|
2020-06-18 00:09:54 +08:00
|
|
|
Context BackgroundContext, const ThreadsafeFS &TFS,
|
2019-01-22 17:10:20 +08:00
|
|
|
const GlobalCompilationDatabase &CDB,
|
[clangd] Show background index status using LSP 3.15 work-done progress notifications
Summary:
It simply shows the completed/total items on the background queue, e.g.
indexing: 233/1000
The denominator is reset to zero every time the queue goes idle.
The protocol is fairly complicated here (requires creating a remote "progress"
resource before sending updates). We implement the full protocol, but I've added
an extension allowing it to be skipped to reduce the burden on clients - in
particular the lit test takes this shortcut.
The addition of background index progress to DiagnosticConsumer seems ridiculous
at first glance, but I believe that interface is trending in the direction of
"ClangdServer callbacks" anyway. It's due for a rename, but otherwise actually
fits.
Reviewers: kadircet, usaxena95
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D73218
2020-01-23 02:41:45 +08:00
|
|
|
BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize,
|
2020-07-03 05:09:25 +08:00
|
|
|
std::function<void(BackgroundQueue::Stats)> OnProgress,
|
|
|
|
std::function<Context(PathRef)> ContextProvider)
|
2020-06-18 00:09:54 +08:00
|
|
|
: SwapIndex(std::make_unique<MemIndex>()), TFS(TFS), CDB(CDB),
|
[clangd] Show background index status using LSP 3.15 work-done progress notifications
Summary:
It simply shows the completed/total items on the background queue, e.g.
indexing: 233/1000
The denominator is reset to zero every time the queue goes idle.
The protocol is fairly complicated here (requires creating a remote "progress"
resource before sending updates). We implement the full protocol, but I've added
an extension allowing it to be skipped to reduce the burden on clients - in
particular the lit test takes this shortcut.
The addition of background index progress to DiagnosticConsumer seems ridiculous
at first glance, but I believe that interface is trending in the direction of
"ClangdServer callbacks" anyway. It's due for a rename, but otherwise actually
fits.
Reviewers: kadircet, usaxena95
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D73218
2020-01-23 02:41:45 +08:00
|
|
|
BackgroundContext(std::move(BackgroundContext)),
|
2020-07-03 05:09:25 +08:00
|
|
|
ContextProvider(std::move(ContextProvider)),
|
2019-07-16 18:17:06 +08:00
|
|
|
Rebuilder(this, &IndexedSymbols, ThreadPoolSize),
|
[clangd] Auto-index watches global CDB for changes.
Summary:
Instead of receiving compilation commands, auto-index is triggered by just
filenames to reindex, and gets commands from the global comp DB internally.
This has advantages:
- more of the work can be done asynchronously (fetching compilation commands
upfront can be slow for large CDBs)
- we get access to the CDB which can be used to retrieve interpolated commands
for headers (useful in some cases where the original TU goes away)
- fits nicely with the filename-only change observation from r347297
The interface to GlobalCompilationDatabase gets extended: when retrieving a
compile command, the GCDB can optionally report the project the file belongs to.
This naturally fits together with getCompileCommand: it's hard to implement one
without the other. But because most callers don't care, I've ended up with an
awkward optional-out-param-in-virtual method pattern - maybe there's a better
one.
This is the main missing integration point between ClangdServer and
BackgroundIndex, after this we should be able to add an auto-index flag.
Reviewers: ioeric, kadircet
Subscribers: MaskRay, jkorous, arphaman, cfe-commits, ilya-biryukov
Differential Revision: https://reviews.llvm.org/D54865
llvm-svn: 347538
2018-11-26 17:51:50 +08:00
|
|
|
IndexStorageFactory(std::move(IndexStorageFactory)),
|
[clangd] Show background index status using LSP 3.15 work-done progress notifications
Summary:
It simply shows the completed/total items on the background queue, e.g.
indexing: 233/1000
The denominator is reset to zero every time the queue goes idle.
The protocol is fairly complicated here (requires creating a remote "progress"
resource before sending updates). We implement the full protocol, but I've added
an extension allowing it to be skipped to reduce the burden on clients - in
particular the lit test takes this shortcut.
The addition of background index progress to DiagnosticConsumer seems ridiculous
at first glance, but I believe that interface is trending in the direction of
"ClangdServer callbacks" anyway. It's due for a rename, but otherwise actually
fits.
Reviewers: kadircet, usaxena95
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D73218
2020-01-23 02:41:45 +08:00
|
|
|
Queue(std::move(OnProgress)),
|
[clangd] Auto-index watches global CDB for changes.
Summary:
Instead of receiving compilation commands, auto-index is triggered by just
filenames to reindex, and gets commands from the global comp DB internally.
This has advantages:
- more of the work can be done asynchronously (fetching compilation commands
upfront can be slow for large CDBs)
- we get access to the CDB which can be used to retrieve interpolated commands
for headers (useful in some cases where the original TU goes away)
- fits nicely with the filename-only change observation from r347297
The interface to GlobalCompilationDatabase gets extended: when retrieving a
compile command, the GCDB can optionally report the project the file belongs to.
This naturally fits together with getCompileCommand: it's hard to implement one
without the other. But because most callers don't care, I've ended up with an
awkward optional-out-param-in-virtual method pattern - maybe there's a better
one.
This is the main missing integration point between ClangdServer and
BackgroundIndex, after this we should be able to add an auto-index flag.
Reviewers: ioeric, kadircet
Subscribers: MaskRay, jkorous, arphaman, cfe-commits, ilya-biryukov
Differential Revision: https://reviews.llvm.org/D54865
llvm-svn: 347538
2018-11-26 17:51:50 +08:00
|
|
|
CommandsChanged(
|
|
|
|
CDB.watch([&](const std::vector<std::string> &ChangedFiles) {
|
|
|
|
enqueue(ChangedFiles);
|
|
|
|
})) {
|
2020-06-23 14:39:30 +08:00
|
|
|
assert(ThreadPoolSize > 0 && "Thread pool size can't be zero.");
|
2018-11-16 17:41:14 +08:00
|
|
|
assert(this->IndexStorageFactory && "Storage factory can not be null!");
|
2020-06-23 14:39:30 +08:00
|
|
|
for (unsigned I = 0; I < ThreadPoolSize; ++I) {
|
2019-07-11 21:34:38 +08:00
|
|
|
ThreadPool.runAsync("background-worker-" + llvm::Twine(I + 1), [this] {
|
|
|
|
WithContext Ctx(this->BackgroundContext.clone());
|
|
|
|
Queue.work([&] { Rebuilder.idle(); });
|
|
|
|
});
|
2019-05-09 20:04:07 +08:00
|
|
|
}
|
2018-10-30 20:13:27 +08:00
|
|
|
}
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
|
|
|
BackgroundIndex::~BackgroundIndex() {
|
|
|
|
stop();
|
2019-05-09 20:04:07 +08:00
|
|
|
ThreadPool.wait();
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-07-11 21:34:38 +08:00
|
|
|
BackgroundQueue::Task BackgroundIndex::changedFilesTask(
|
|
|
|
const std::vector<std::string> &ChangedFiles) {
|
|
|
|
BackgroundQueue::Task T([this, ChangedFiles] {
|
|
|
|
trace::Span Tracer("BackgroundIndexEnqueue");
|
2020-07-03 05:09:25 +08:00
|
|
|
|
|
|
|
llvm::Optional<WithContext> WithProvidedContext;
|
|
|
|
if (ContextProvider)
|
|
|
|
WithProvidedContext.emplace(ContextProvider(/*Path=*/""));
|
|
|
|
|
2019-07-11 21:34:38 +08:00
|
|
|
// We're doing this asynchronously, because we'll read shards here too.
|
|
|
|
log("Enqueueing {0} commands for indexing", ChangedFiles.size());
|
|
|
|
SPAN_ATTACH(Tracer, "files", int64_t(ChangedFiles.size()));
|
|
|
|
|
2019-07-19 18:18:52 +08:00
|
|
|
auto NeedsReIndexing = loadProject(std::move(ChangedFiles));
|
2019-07-11 21:34:38 +08:00
|
|
|
// Run indexing for files that need to be updated.
|
|
|
|
std::shuffle(NeedsReIndexing.begin(), NeedsReIndexing.end(),
|
|
|
|
std::mt19937(std::random_device{}()));
|
|
|
|
std::vector<BackgroundQueue::Task> Tasks;
|
|
|
|
Tasks.reserve(NeedsReIndexing.size());
|
2019-07-19 18:18:52 +08:00
|
|
|
for (auto &Cmd : NeedsReIndexing)
|
|
|
|
Tasks.push_back(indexFileTask(std::move(Cmd)));
|
2019-07-11 21:34:38 +08:00
|
|
|
Queue.append(std::move(Tasks));
|
|
|
|
});
|
|
|
|
|
|
|
|
T.QueuePri = LoadShards;
|
|
|
|
T.ThreadPri = llvm::ThreadPriority::Default;
|
|
|
|
return T;
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-07-12 18:18:42 +08:00
|
|
|
static llvm::StringRef filenameWithoutExtension(llvm::StringRef Path) {
|
|
|
|
Path = llvm::sys::path::filename(Path);
|
|
|
|
return Path.drop_back(llvm::sys::path::extension(Path).size());
|
|
|
|
}
|
|
|
|
|
2020-07-03 05:09:25 +08:00
|
|
|
BackgroundQueue::Task BackgroundIndex::indexFileTask(std::string Path) {
|
|
|
|
std::string Tag = filenameWithoutExtension(Path).str();
|
|
|
|
BackgroundQueue::Task T([this, Path(std::move(Path))] {
|
|
|
|
llvm::Optional<WithContext> WithProvidedContext;
|
|
|
|
if (ContextProvider)
|
|
|
|
WithProvidedContext.emplace(ContextProvider(Path));
|
|
|
|
auto Cmd = CDB.getCompileCommand(Path);
|
|
|
|
if (!Cmd)
|
|
|
|
return;
|
|
|
|
if (auto Error = index(std::move(*Cmd)))
|
|
|
|
elog("Indexing {0} failed: {1}", Path, std::move(Error));
|
2019-07-11 21:34:38 +08:00
|
|
|
});
|
|
|
|
T.QueuePri = IndexFile;
|
2020-07-03 05:09:25 +08:00
|
|
|
T.Tag = std::move(Tag);
|
2019-07-11 21:34:38 +08:00
|
|
|
return T;
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-07-12 18:18:42 +08:00
|
|
|
void BackgroundIndex::boostRelated(llvm::StringRef Path) {
|
[clangd] Add isHeaderFile helper.
Summary:
we have a few places using `ASTCtx.getLangOpts().IsHeaderFile` to
determine a header file, but it relies on "-x c-header" compiler flag,
if the compilation command doesn't have this flag, we will get a false
positive. We are encountering this issue in bazel build system.
To solve this problem, we infer the file from file name, actual changes will
come in follow-ups.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D70235
2019-11-13 23:30:07 +08:00
|
|
|
if (isHeaderFile(Path))
|
2019-07-12 18:18:42 +08:00
|
|
|
Queue.boost(filenameWithoutExtension(Path), IndexBoostedFile);
|
|
|
|
}
|
|
|
|
|
2019-01-15 17:03:33 +08:00
|
|
|
/// Given index results from a TU, only update symbols coming from files that
|
2019-07-04 17:52:12 +08:00
|
|
|
/// are different or missing from than \p ShardVersionsSnapshot. Also stores new
|
|
|
|
/// index information on IndexStorage.
|
|
|
|
void BackgroundIndex::update(
|
|
|
|
llvm::StringRef MainFile, IndexFileIn Index,
|
|
|
|
const llvm::StringMap<ShardVersion> &ShardVersionsSnapshot,
|
2019-07-19 18:18:52 +08:00
|
|
|
bool HadErrors) {
|
2020-04-29 17:21:14 +08:00
|
|
|
// Keys are URIs.
|
|
|
|
llvm::StringMap<std::pair<Path, FileDigest>> FilesToUpdate;
|
|
|
|
// Note that sources do not contain any information regarding missing headers,
|
|
|
|
// since we don't even know what absolute path they should fall in.
|
2019-01-15 17:03:33 +08:00
|
|
|
for (const auto &IndexIt : *Index.Sources) {
|
|
|
|
const auto &IGN = IndexIt.getValue();
|
2020-04-29 17:21:14 +08:00
|
|
|
auto AbsPath = URI::resolve(IGN.URI, MainFile);
|
|
|
|
if (!AbsPath) {
|
|
|
|
elog("Failed to resolve URI: {0}", AbsPath.takeError());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const auto DigestIt = ShardVersionsSnapshot.find(*AbsPath);
|
2020-04-05 14:28:11 +08:00
|
|
|
// File has different contents, or indexing was successful this time.
|
2019-07-04 17:52:12 +08:00
|
|
|
if (DigestIt == ShardVersionsSnapshot.end() ||
|
|
|
|
DigestIt->getValue().Digest != IGN.Digest ||
|
|
|
|
(DigestIt->getValue().HadErrors && !HadErrors))
|
2020-04-29 17:21:14 +08:00
|
|
|
FilesToUpdate[IGN.URI] = {std::move(*AbsPath), IGN.Digest};
|
2019-06-15 10:26:47 +08:00
|
|
|
}
|
2018-11-06 18:55:21 +08:00
|
|
|
|
2020-04-08 22:14:53 +08:00
|
|
|
// Shard slabs into files.
|
2020-04-29 17:21:14 +08:00
|
|
|
FileShardedIndex ShardedIndex(std::move(Index));
|
2019-07-04 17:51:43 +08:00
|
|
|
|
2020-04-08 22:14:53 +08:00
|
|
|
// Build and store new slabs for each updated file.
|
|
|
|
for (const auto &FileIt : FilesToUpdate) {
|
2020-04-29 17:21:14 +08:00
|
|
|
auto Uri = FileIt.first();
|
2020-04-30 22:40:56 +08:00
|
|
|
auto IF = ShardedIndex.getShard(Uri);
|
|
|
|
assert(IF && "no shard for file in Index.Sources?");
|
2020-04-29 17:21:14 +08:00
|
|
|
PathRef Path = FileIt.getValue().first;
|
2019-07-19 18:18:52 +08:00
|
|
|
|
|
|
|
// Only store command line hash for main files of the TU, since our
|
|
|
|
// current model keeps only one version of a header file.
|
2020-04-08 22:14:53 +08:00
|
|
|
if (Path != MainFile)
|
2020-04-30 22:40:56 +08:00
|
|
|
IF->Cmd.reset();
|
2019-07-19 18:18:52 +08:00
|
|
|
|
2020-04-08 22:14:53 +08:00
|
|
|
// We need to store shards before updating the index, since the latter
|
|
|
|
// consumes slabs.
|
|
|
|
// FIXME: Also skip serializing the shard if it is already up-to-date.
|
2020-04-30 22:40:56 +08:00
|
|
|
if (auto Error = IndexStorageFactory(Path)->storeShard(Path, *IF))
|
2019-07-19 18:18:52 +08:00
|
|
|
elog("Failed to write background-index shard for file {0}: {1}", Path,
|
|
|
|
std::move(Error));
|
2019-07-04 17:51:43 +08:00
|
|
|
|
2019-01-11 01:03:04 +08:00
|
|
|
{
|
2019-07-04 17:52:12 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(ShardVersionsMu);
|
2020-04-29 17:21:14 +08:00
|
|
|
const auto &Hash = FileIt.getValue().second;
|
2019-07-04 17:52:12 +08:00
|
|
|
auto DigestIt = ShardVersions.try_emplace(Path);
|
|
|
|
ShardVersion &SV = DigestIt.first->second;
|
|
|
|
// Skip if file is already up to date, unless previous index was broken
|
|
|
|
// and this one is not.
|
|
|
|
if (!DigestIt.second && SV.Digest == Hash && SV.HadErrors && !HadErrors)
|
2019-01-11 01:03:04 +08:00
|
|
|
continue;
|
2019-07-04 17:52:12 +08:00
|
|
|
SV.Digest = Hash;
|
|
|
|
SV.HadErrors = HadErrors;
|
|
|
|
|
2019-01-11 01:03:04 +08:00
|
|
|
// This can override a newer version that is added in another thread, if
|
|
|
|
// this thread sees the older version but finishes later. This should be
|
|
|
|
// rare in practice.
|
2020-04-08 22:14:53 +08:00
|
|
|
IndexedSymbols.update(
|
2020-04-30 22:40:56 +08:00
|
|
|
Path, std::make_unique<SymbolSlab>(std::move(*IF->Symbols)),
|
|
|
|
std::make_unique<RefSlab>(std::move(*IF->Refs)),
|
|
|
|
std::make_unique<RelationSlab>(std::move(*IF->Relations)),
|
2020-04-08 22:14:53 +08:00
|
|
|
Path == MainFile);
|
2019-01-11 01:03:04 +08:00
|
|
|
}
|
2018-11-06 18:55:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-19 18:18:52 +08:00
|
|
|
llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) {
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
trace::Span Tracer("BackgroundIndex");
|
|
|
|
SPAN_ATTACH(Tracer, "file", Cmd.Filename);
|
2019-01-11 01:03:04 +08:00
|
|
|
auto AbsolutePath = getAbsolutePath(Cmd);
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
2020-06-18 00:09:54 +08:00
|
|
|
auto FS = TFS.view(Cmd.Directory);
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
auto Buf = FS->getBufferForFile(AbsolutePath);
|
|
|
|
if (!Buf)
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::errorCodeToError(Buf.getError());
|
2018-11-06 18:55:21 +08:00
|
|
|
auto Hash = digest(Buf->get()->getBuffer());
|
|
|
|
|
2019-07-04 17:52:12 +08:00
|
|
|
// Take a snapshot of the versions to avoid locking for each file in the TU.
|
|
|
|
llvm::StringMap<ShardVersion> ShardVersionsSnapshot;
|
2018-11-06 18:55:21 +08:00
|
|
|
{
|
2019-07-04 17:52:12 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(ShardVersionsMu);
|
|
|
|
ShardVersionsSnapshot = ShardVersions;
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-01-19 01:04:26 +08:00
|
|
|
vlog("Indexing {0} (digest:={1})", Cmd.Filename, llvm::toHex(Hash));
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
ParseInputs Inputs;
|
2020-06-18 00:09:54 +08:00
|
|
|
Inputs.TFS = &TFS;
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
Inputs.CompileCommand = std::move(Cmd);
|
[clangd] Surface errors from command-line parsing
Summary:
Those errors are exposed at the first character of a file,
for a lack of a better place.
Previously, all errors were stored inside the AST and report
accordingly. However, errors in command-line argument parsing could
result in failure to produce the AST, so we need an alternative ways to
report those errors.
We take the following approach in this patch:
- buildCompilerInvocation() now requires an explicit DiagnosticConsumer.
- TUScheduler and TestTU now collect the diagnostics produced when
parsing command line arguments.
If pasing of the AST failed, diagnostics are reported via a new
ParsingCallbacks::onFailedAST method.
If parsing of the AST succeeded, any errors produced during
command-line parsing are stored alongside the AST inside the
ParsedAST instance and reported as previously by calling the
ParsingCallbacks::onMainAST method;
- The client code that uses ClangdServer's DiagnosticConsumer
does not need to change, it will receive new diagnostics in the
onDiagnosticsReady() callback
Errors produced when parsing command-line arguments are collected using
the same StoreDiags class that is used to collect all other errors. They
are recognized by their location being invalid. IIUC, the location is
invalid as there is no source manager at this point, it is created at a
later stage.
Although technically we might also get diagnostics that mention the
command-line arguments FileID with after the source manager was created
(and they have valid source locations), we choose to not handle those
and they are dropped as not coming from the main file. AFAICT, those
diagnostics should always be notes, therefore it's safe to drop them
without loosing too much information.
Reviewers: kadircet
Reviewed By: kadircet
Subscribers: nridge, javed.absar, MaskRay, jkorous, arphaman, cfe-commits, gribozavr
Tags: #clang
Differential Revision: https://reviews.llvm.org/D66759
llvm-svn: 370177
2019-08-28 17:24:55 +08:00
|
|
|
IgnoreDiagnostics IgnoreDiags;
|
|
|
|
auto CI = buildCompilerInvocation(Inputs, IgnoreDiags);
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
if (!CI)
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
|
|
"Couldn't build compiler invocation");
|
2020-06-05 00:26:52 +08:00
|
|
|
|
|
|
|
auto Clang =
|
|
|
|
prepareCompilerInstance(std::move(CI), /*Preamble=*/nullptr,
|
|
|
|
std::move(*Buf), std::move(FS), IgnoreDiags);
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
if (!Clang)
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
|
|
"Couldn't build compiler instance");
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
|
|
|
SymbolCollector::Options IndexOpts;
|
2019-07-04 17:52:12 +08:00
|
|
|
// Creates a filter to not collect index results from files with unchanged
|
|
|
|
// digests.
|
|
|
|
IndexOpts.FileFilter = [&ShardVersionsSnapshot](const SourceManager &SM,
|
|
|
|
FileID FID) {
|
|
|
|
const auto *F = SM.getFileEntryForID(FID);
|
|
|
|
if (!F)
|
|
|
|
return false; // Skip invalid files.
|
|
|
|
auto AbsPath = getCanonicalPath(F, SM);
|
|
|
|
if (!AbsPath)
|
|
|
|
return false; // Skip files without absolute path.
|
|
|
|
auto Digest = digestFile(SM, FID);
|
|
|
|
if (!Digest)
|
|
|
|
return false;
|
|
|
|
auto D = ShardVersionsSnapshot.find(*AbsPath);
|
|
|
|
if (D != ShardVersionsSnapshot.end() && D->second.Digest == Digest &&
|
|
|
|
!D->second.HadErrors)
|
|
|
|
return false; // Skip files that haven't changed, without errors.
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2018-12-04 19:31:57 +08:00
|
|
|
IndexFileIn Index;
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
auto Action = createStaticIndexingAction(
|
2018-12-04 19:31:57 +08:00
|
|
|
IndexOpts, [&](SymbolSlab S) { Index.Symbols = std::move(S); },
|
|
|
|
[&](RefSlab R) { Index.Refs = std::move(R); },
|
2019-06-15 10:26:47 +08:00
|
|
|
[&](RelationSlab R) { Index.Relations = std::move(R); },
|
2018-12-04 19:31:57 +08:00
|
|
|
[&](IncludeGraph IG) { Index.Sources = std::move(IG); });
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
|
|
|
// We're going to run clang here, and it could potentially crash.
|
|
|
|
// We could use CrashRecoveryContext to try to make indexing crashes nonfatal,
|
|
|
|
// but the leaky "recovery" is pretty scary too in a long-running process.
|
|
|
|
// If crashes are a real problem, maybe we should fork a child process.
|
|
|
|
|
|
|
|
const FrontendInputFile &Input = Clang->getFrontendOpts().Inputs.front();
|
|
|
|
if (!Action->BeginSourceFile(*Clang, Input))
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
|
|
"BeginSourceFile() failed");
|
2019-06-27 03:50:12 +08:00
|
|
|
if (llvm::Error Err = Action->Execute())
|
|
|
|
return Err;
|
|
|
|
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
Action->EndSourceFile();
|
2018-12-14 20:39:08 +08:00
|
|
|
|
2019-07-04 17:51:53 +08:00
|
|
|
Index.Cmd = Inputs.CompileCommand;
|
2019-01-11 01:03:04 +08:00
|
|
|
assert(Index.Symbols && Index.Refs && Index.Sources &&
|
|
|
|
"Symbols, Refs and Sources must be set.");
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
2018-12-04 19:31:57 +08:00
|
|
|
log("Indexed {0} ({1} symbols, {2} refs, {3} files)",
|
|
|
|
Inputs.CompileCommand.Filename, Index.Symbols->size(),
|
|
|
|
Index.Refs->numRefs(), Index.Sources->size());
|
|
|
|
SPAN_ATTACH(Tracer, "symbols", int(Index.Symbols->size()));
|
|
|
|
SPAN_ATTACH(Tracer, "refs", int(Index.Refs->numRefs()));
|
|
|
|
SPAN_ATTACH(Tracer, "sources", int(Index.Sources->size()));
|
2018-11-28 00:08:53 +08:00
|
|
|
|
2019-07-04 17:51:43 +08:00
|
|
|
bool HadErrors = Clang->hasDiagnostics() &&
|
|
|
|
Clang->getDiagnostics().hasUncompilableErrorOccurred();
|
2019-07-04 17:52:04 +08:00
|
|
|
if (HadErrors) {
|
|
|
|
log("Failed to compile {0}, index may be incomplete", AbsolutePath);
|
|
|
|
for (auto &It : *Index.Sources)
|
|
|
|
It.second.Flags |= IncludeGraphNode::SourceFlag::HadErrors;
|
|
|
|
}
|
2019-07-19 18:18:52 +08:00
|
|
|
update(AbsolutePath, std::move(Index), ShardVersionsSnapshot, HadErrors);
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
[clangd] Rewrite of logic to rebuild the background index serving structures.
Summary:
Previously it was rebuilding every 5s by default, which was much too frequent
in the long run - the goal was to provide an early build. There were also some
bugs. There were also some bugs, and a dedicated thread was used in production
but not tested.
- rebuilds are triggered by #TUs built, rather than time. This should scale
more sensibly to fast vs slow machines.
- there are two separate indexed-TU thresholds to trigger index build: 5 TUs
for the first build, 100 for subsequent rebuilds.
- rebuild is always done on the regular indexing threads, and is affected by
blockUntilIdle. This means unit/lit tests run the production configuration.
- fixed a bug where we'd rebuild after attempting to load shards, even if there
were no shards.
- the BackgroundIndexTests don't really test the subtleties of the rebuild
policy (for determinism, we call blockUntilIdle, so rebuild-on-idle is enough
to pass the tests). Instead, we expose the rebuilder as a separate class and
have fine-grained tests for it.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64291
llvm-svn: 365531
2019-07-10 02:30:49 +08:00
|
|
|
Rebuilder.indexedTU();
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::Error::success();
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-07-19 18:18:52 +08:00
|
|
|
// Restores shards for \p MainFiles from index storage. Then checks staleness of
|
|
|
|
// those shards and returns a list of TUs that needs to be indexed to update
|
|
|
|
// staleness.
|
2020-07-03 05:09:25 +08:00
|
|
|
std::vector<std::string>
|
2019-07-19 18:18:52 +08:00
|
|
|
BackgroundIndex::loadProject(std::vector<std::string> MainFiles) {
|
2020-07-14 21:17:16 +08:00
|
|
|
// Drop files where background indexing is disabled in config.
|
|
|
|
if (ContextProvider)
|
|
|
|
llvm::erase_if(MainFiles, [&](const std::string &TU) {
|
|
|
|
// Load the config for each TU, as indexing may be selectively enabled.
|
|
|
|
WithContext WithProvidedContext(ContextProvider(TU));
|
|
|
|
return Config::current().Index.Background ==
|
|
|
|
Config::BackgroundPolicy::Skip;
|
|
|
|
});
|
2019-07-19 18:18:52 +08:00
|
|
|
Rebuilder.startLoading();
|
|
|
|
// Load shards for all of the mainfiles.
|
|
|
|
const std::vector<LoadedShard> Result =
|
|
|
|
loadIndexShards(MainFiles, IndexStorageFactory, CDB);
|
|
|
|
size_t LoadedShards = 0;
|
2019-01-11 01:03:04 +08:00
|
|
|
{
|
2019-07-19 18:18:52 +08:00
|
|
|
// Update in-memory state.
|
2019-07-04 17:52:12 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(ShardVersionsMu);
|
2019-07-19 18:18:52 +08:00
|
|
|
for (auto &LS : Result) {
|
|
|
|
if (!LS.Shard)
|
|
|
|
continue;
|
2019-01-11 01:03:04 +08:00
|
|
|
auto SS =
|
2019-07-19 18:18:52 +08:00
|
|
|
LS.Shard->Symbols
|
2019-08-15 07:52:23 +08:00
|
|
|
? std::make_unique<SymbolSlab>(std::move(*LS.Shard->Symbols))
|
2019-01-11 01:03:04 +08:00
|
|
|
: nullptr;
|
2019-07-19 18:18:52 +08:00
|
|
|
auto RS = LS.Shard->Refs
|
2019-08-15 07:52:23 +08:00
|
|
|
? std::make_unique<RefSlab>(std::move(*LS.Shard->Refs))
|
2019-01-11 01:03:04 +08:00
|
|
|
: nullptr;
|
2019-06-15 10:26:47 +08:00
|
|
|
auto RelS =
|
2019-07-19 18:18:52 +08:00
|
|
|
LS.Shard->Relations
|
2019-08-15 07:52:23 +08:00
|
|
|
? std::make_unique<RelationSlab>(std::move(*LS.Shard->Relations))
|
2019-06-15 10:26:47 +08:00
|
|
|
: nullptr;
|
2019-07-19 18:18:52 +08:00
|
|
|
ShardVersion &SV = ShardVersions[LS.AbsolutePath];
|
|
|
|
SV.Digest = LS.Digest;
|
|
|
|
SV.HadErrors = LS.HadErrors;
|
|
|
|
++LoadedShards;
|
2019-07-04 17:52:12 +08:00
|
|
|
|
2019-07-19 18:18:52 +08:00
|
|
|
IndexedSymbols.update(LS.AbsolutePath, std::move(SS), std::move(RS),
|
|
|
|
std::move(RelS), LS.CountReferences);
|
2019-01-11 01:03:04 +08:00
|
|
|
}
|
|
|
|
}
|
2019-07-19 18:18:52 +08:00
|
|
|
Rebuilder.loadedShard(LoadedShards);
|
|
|
|
Rebuilder.doneLoading();
|
2019-01-11 01:03:04 +08:00
|
|
|
|
2020-06-18 00:09:54 +08:00
|
|
|
auto FS = TFS.view(/*CWD=*/llvm::None);
|
2019-07-19 18:18:52 +08:00
|
|
|
llvm::DenseSet<PathRef> TUsToIndex;
|
|
|
|
// We'll accept data from stale shards, but ensure the files get reindexed
|
|
|
|
// soon.
|
|
|
|
for (auto &LS : Result) {
|
|
|
|
if (!shardIsStale(LS, FS.get()))
|
|
|
|
continue;
|
|
|
|
PathRef TUForFile = LS.DependentTU;
|
|
|
|
assert(!TUForFile.empty() && "File without a TU!");
|
|
|
|
|
|
|
|
// FIXME: Currently, we simply schedule indexing on a TU whenever any of
|
|
|
|
// its dependencies needs re-indexing. We might do it smarter by figuring
|
|
|
|
// out a minimal set of TUs that will cover all the stale dependencies.
|
|
|
|
// FIXME: Try looking at other TUs if no compile commands are available
|
|
|
|
// for this TU, i.e TU was deleted after we performed indexing.
|
|
|
|
TUsToIndex.insert(TUForFile);
|
|
|
|
}
|
2019-01-11 01:03:04 +08:00
|
|
|
|
2020-07-03 05:09:25 +08:00
|
|
|
return {TUsToIndex.begin(), TUsToIndex.end()};
|
2019-01-11 01:03:04 +08:00
|
|
|
}
|
|
|
|
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|