[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 ------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "index/Background.h"
|
|
|
|
#include "ClangdUnit.h"
|
|
|
|
#include "Compiler.h"
|
|
|
|
#include "Logger.h"
|
2018-11-28 00:08:53 +08:00
|
|
|
#include "SourceCode.h"
|
2018-10-30 20:13:27 +08:00
|
|
|
#include "Threading.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 "Trace.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "URI.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"
|
|
|
|
#include "index/Serialization.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "index/SymbolCollector.h"
|
|
|
|
#include "clang/Basic/SourceLocation.h"
|
|
|
|
#include "clang/Basic/SourceManager.h"
|
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
|
|
#include "llvm/ADT/StringRef.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 "llvm/Support/SHA1.h"
|
2018-11-16 17:03:56 +08:00
|
|
|
|
|
|
|
#include <memory>
|
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>
|
[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
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
2018-12-04 19:31:57 +08:00
|
|
|
namespace {
|
|
|
|
// Resolves URI to file paths with cache.
|
|
|
|
class URIToFileCache {
|
|
|
|
public:
|
|
|
|
URIToFileCache(llvm::StringRef HintPath) : HintPath(HintPath) {}
|
|
|
|
|
|
|
|
llvm::StringRef resolve(llvm::StringRef FileURI) {
|
|
|
|
auto I = URIToPathCache.try_emplace(FileURI);
|
|
|
|
if (I.second) {
|
|
|
|
auto U = URI::parse(FileURI);
|
|
|
|
if (!U) {
|
|
|
|
elog("Failed to parse URI {0}: {1}", FileURI, U.takeError());
|
|
|
|
assert(false && "Failed to parse URI");
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
auto Path = URI::resolve(*U, HintPath);
|
|
|
|
if (!Path) {
|
|
|
|
elog("Failed to resolve URI {0}: {1}", FileURI, Path.takeError());
|
|
|
|
assert(false && "Failed to resolve URI");
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
I.first->second = *Path;
|
|
|
|
}
|
|
|
|
return I.first->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::string HintPath;
|
|
|
|
llvm::StringMap<std::string> URIToPathCache;
|
|
|
|
};
|
|
|
|
|
|
|
|
// We keep only the node "U" and its edges. Any node other than "U" will be
|
|
|
|
// empty in the resultant graph.
|
|
|
|
IncludeGraph getSubGraph(const URI &U, const IncludeGraph &FullGraph) {
|
|
|
|
IncludeGraph IG;
|
|
|
|
|
|
|
|
std::string FileURI = U.toString();
|
|
|
|
auto Entry = IG.try_emplace(FileURI).first;
|
|
|
|
auto &Node = Entry->getValue();
|
|
|
|
Node = FullGraph.lookup(Entry->getKey());
|
|
|
|
Node.URI = Entry->getKey();
|
|
|
|
|
|
|
|
// URIs inside nodes must point into the keys of the same IncludeGraph.
|
|
|
|
for (auto &Include : Node.DirectIncludes) {
|
|
|
|
auto I = IG.try_emplace(Include).first;
|
|
|
|
I->getValue().URI = I->getKey();
|
|
|
|
Include = I->getKey();
|
|
|
|
}
|
|
|
|
|
|
|
|
return IG;
|
|
|
|
}
|
|
|
|
} // 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(
|
|
|
|
Context BackgroundContext, StringRef ResourceDir,
|
[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
|
|
|
const FileSystemProvider &FSProvider, const GlobalCompilationDatabase &CDB,
|
2018-11-16 17:03:56 +08:00
|
|
|
BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize)
|
2018-10-20 23:30:37 +08:00
|
|
|
: SwapIndex(make_unique<MemIndex>()), ResourceDir(ResourceDir),
|
[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
|
|
|
FSProvider(FSProvider), CDB(CDB),
|
|
|
|
BackgroundContext(std::move(BackgroundContext)),
|
|
|
|
IndexStorageFactory(std::move(IndexStorageFactory)),
|
|
|
|
CommandsChanged(
|
|
|
|
CDB.watch([&](const std::vector<std::string> &ChangedFiles) {
|
|
|
|
enqueue(ChangedFiles);
|
|
|
|
})) {
|
2018-10-30 20:13:27 +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!");
|
2018-10-30 20:13:27 +08:00
|
|
|
while (ThreadPoolSize--) {
|
|
|
|
ThreadPool.emplace_back([this] { run(); });
|
|
|
|
// Set priority to low, since background indexing is a long running task we
|
|
|
|
// do not want to eat up cpu when there are any other high priority threads.
|
|
|
|
// FIXME: In the future we might want a more general way of handling this to
|
2018-11-16 17:03:56 +08:00
|
|
|
// support tasks with various priorities.
|
2018-10-30 20:13:27 +08:00
|
|
|
setThreadPriority(ThreadPool.back(), ThreadPriority::Low);
|
|
|
|
}
|
|
|
|
}
|
[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();
|
2018-10-30 20:13:27 +08:00
|
|
|
for (auto &Thread : ThreadPool)
|
|
|
|
Thread.join();
|
[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
|
|
|
}
|
|
|
|
|
|
|
|
void BackgroundIndex::stop() {
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> Lock(QueueMu);
|
|
|
|
ShouldStop = true;
|
|
|
|
}
|
|
|
|
QueueCV.notify_all();
|
|
|
|
}
|
|
|
|
|
|
|
|
void BackgroundIndex::run() {
|
2018-10-30 20:13:27 +08:00
|
|
|
WithContext Background(BackgroundContext.clone());
|
[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
|
|
|
while (true) {
|
2018-10-20 23:30:37 +08:00
|
|
|
Optional<Task> Task;
|
[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
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> Lock(QueueMu);
|
|
|
|
QueueCV.wait(Lock, [&] { return ShouldStop || !Queue.empty(); });
|
|
|
|
if (ShouldStop) {
|
|
|
|
Queue.clear();
|
|
|
|
QueueCV.notify_all();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
++NumActiveTasks;
|
|
|
|
Task = std::move(Queue.front());
|
|
|
|
Queue.pop_front();
|
|
|
|
}
|
|
|
|
(*Task)();
|
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> Lock(QueueMu);
|
|
|
|
assert(NumActiveTasks > 0 && "before decrementing");
|
|
|
|
--NumActiveTasks;
|
|
|
|
}
|
|
|
|
QueueCV.notify_all();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[clangd] Enable auto-index behind a flag.
Summary:
Ownership and configuration:
The auto-index (background index) is maintained by ClangdServer, like Dynamic.
(This means ClangdServer will be able to enqueue preamble indexing in future).
For now it's enabled by a simple boolean flag in ClangdServer::Options, but
we probably want to eventually allow injecting the storage strategy.
New 'sync' command:
In order to meaningfully test the integration (not just unit-test components)
we need a way for tests to ensure the asynchronous index reads/writes occur
before a certain point.
Because these tests and assertions are few, I think exposing an explicit "sync"
command for use in tests is simpler than allowing threading to be completely
disabled in the background index (as we do for TUScheduler).
Bugs:
I fixed a couple of trivial bugs I found while testing, but there's one I can't.
JSONCompilationDatabase::getAllFiles() may return relative paths, and currently
we trigger an assertion that assumes they are absolute.
There's no efficient way to resolve them (you have to retrieve the corresponding
command and then resolve against its directory property). In general I think
this behavior is broken and we should fix it in JSONCompilationDatabase and
require CompilationDatabase::getAllFiles() to be absolute.
Reviewers: kadircet
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D54894
llvm-svn: 347567
2018-11-27 00:00:11 +08:00
|
|
|
bool BackgroundIndex::blockUntilIdleForTest(
|
|
|
|
llvm::Optional<double> TimeoutSeconds) {
|
[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
|
|
|
std::unique_lock<std::mutex> Lock(QueueMu);
|
[clangd] Enable auto-index behind a flag.
Summary:
Ownership and configuration:
The auto-index (background index) is maintained by ClangdServer, like Dynamic.
(This means ClangdServer will be able to enqueue preamble indexing in future).
For now it's enabled by a simple boolean flag in ClangdServer::Options, but
we probably want to eventually allow injecting the storage strategy.
New 'sync' command:
In order to meaningfully test the integration (not just unit-test components)
we need a way for tests to ensure the asynchronous index reads/writes occur
before a certain point.
Because these tests and assertions are few, I think exposing an explicit "sync"
command for use in tests is simpler than allowing threading to be completely
disabled in the background index (as we do for TUScheduler).
Bugs:
I fixed a couple of trivial bugs I found while testing, but there's one I can't.
JSONCompilationDatabase::getAllFiles() may return relative paths, and currently
we trigger an assertion that assumes they are absolute.
There's no efficient way to resolve them (you have to retrieve the corresponding
command and then resolve against its directory property). In general I think
this behavior is broken and we should fix it in JSONCompilationDatabase and
require CompilationDatabase::getAllFiles() to be absolute.
Reviewers: kadircet
Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits
Differential Revision: https://reviews.llvm.org/D54894
llvm-svn: 347567
2018-11-27 00:00:11 +08:00
|
|
|
return wait(Lock, QueueCV, timeoutSeconds(TimeoutSeconds),
|
|
|
|
[&] { return Queue.empty() && NumActiveTasks == 0; });
|
[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] 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
|
|
|
void BackgroundIndex::enqueue(const std::vector<std::string> &ChangedFiles) {
|
|
|
|
enqueueTask([this, ChangedFiles] {
|
|
|
|
trace::Span Tracer("BackgroundIndexEnqueue");
|
|
|
|
// We're doing this asynchronously, because we'll read shards here too.
|
|
|
|
// FIXME: read shards here too.
|
|
|
|
|
|
|
|
log("Enqueueing {0} commands for indexing", ChangedFiles.size());
|
|
|
|
SPAN_ATTACH(Tracer, "files", int64_t(ChangedFiles.size()));
|
|
|
|
|
|
|
|
// We shuffle the files because processing them in a random order should
|
|
|
|
// quickly give us good coverage of headers in the project.
|
|
|
|
std::vector<unsigned> Permutation(ChangedFiles.size());
|
|
|
|
std::iota(Permutation.begin(), Permutation.end(), 0);
|
|
|
|
std::mt19937 Generator(std::random_device{}());
|
|
|
|
std::shuffle(Permutation.begin(), Permutation.end(), Generator);
|
|
|
|
|
|
|
|
for (const unsigned I : Permutation)
|
|
|
|
enqueue(ChangedFiles[I]);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void BackgroundIndex::enqueue(const std::string &File) {
|
|
|
|
ProjectInfo Project;
|
|
|
|
if (auto Cmd = CDB.getCompileCommand(File, &Project)) {
|
|
|
|
auto *Storage = IndexStorageFactory(Project.SourceRoot);
|
|
|
|
enqueueTask(Bind(
|
|
|
|
[this, File, Storage](tooling::CompileCommand Cmd) {
|
|
|
|
Cmd.CommandLine.push_back("-resource-dir=" + ResourceDir);
|
|
|
|
if (auto Error = index(std::move(Cmd), Storage))
|
|
|
|
log("Indexing {0} failed: {1}", File, std::move(Error));
|
|
|
|
},
|
|
|
|
std::move(*Cmd)));
|
[clangd] Fix threading bugs in (not-yet-used) BackgroundIndex, re-enable test.
Summary:
One relatively boring bug: forgot to notify the CV after enqueue.
One much more fun bug: the thread member could access instance variables before
they were initialized. Although the thread was last in the init list, QueueCV
etc were listed after Thread in the class, so their default constructors raced
with the thread itself.
We have to get very unlucky to lose this race, I saw it 0.02% of the time.
Reviewers: ioeric
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53313
llvm-svn: 344595
2018-10-16 17:05:13 +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
|
|
|
}
|
|
|
|
|
[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
|
|
|
void BackgroundIndex::enqueueTask(Task 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
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> Lock(QueueMu);
|
[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
|
|
|
Queue.push_back(std::move(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
|
|
|
}
|
|
|
|
QueueCV.notify_all();
|
|
|
|
}
|
|
|
|
|
2018-11-06 18:55:21 +08:00
|
|
|
/// Given index results from a TU, only update files in \p FilesToUpdate.
|
2018-11-28 00:08:53 +08:00
|
|
|
void BackgroundIndex::update(StringRef MainFile, IndexFileIn Index,
|
2018-11-16 17:03:56 +08:00
|
|
|
const StringMap<FileDigest> &FilesToUpdate,
|
|
|
|
BackgroundIndexStorage *IndexStorage) {
|
2018-11-06 18:55:21 +08:00
|
|
|
// Partition symbols/references into files.
|
|
|
|
struct File {
|
|
|
|
DenseSet<const Symbol *> Symbols;
|
|
|
|
DenseSet<const Ref *> Refs;
|
|
|
|
};
|
|
|
|
StringMap<File> Files;
|
|
|
|
URIToFileCache URICache(MainFile);
|
2018-11-28 00:08:53 +08:00
|
|
|
for (const auto &Sym : *Index.Symbols) {
|
2018-11-06 18:55:21 +08:00
|
|
|
if (Sym.CanonicalDeclaration) {
|
|
|
|
auto DeclPath = URICache.resolve(Sym.CanonicalDeclaration.FileURI);
|
|
|
|
if (FilesToUpdate.count(DeclPath) != 0)
|
|
|
|
Files[DeclPath].Symbols.insert(&Sym);
|
|
|
|
}
|
|
|
|
// For symbols with different declaration and definition locations, we store
|
|
|
|
// the full symbol in both the header file and the implementation file, so
|
|
|
|
// that merging can tell the preferred symbols (from canonical headers) from
|
|
|
|
// other symbols (e.g. forward declarations).
|
|
|
|
if (Sym.Definition &&
|
|
|
|
Sym.Definition.FileURI != Sym.CanonicalDeclaration.FileURI) {
|
|
|
|
auto DefPath = URICache.resolve(Sym.Definition.FileURI);
|
|
|
|
if (FilesToUpdate.count(DefPath) != 0)
|
|
|
|
Files[DefPath].Symbols.insert(&Sym);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DenseMap<const Ref *, SymbolID> RefToIDs;
|
2018-11-28 00:08:53 +08:00
|
|
|
for (const auto &SymRefs : *Index.Refs) {
|
2018-11-06 18:55:21 +08:00
|
|
|
for (const auto &R : SymRefs.second) {
|
|
|
|
auto Path = URICache.resolve(R.Location.FileURI);
|
|
|
|
if (FilesToUpdate.count(Path) != 0) {
|
|
|
|
auto &F = Files[Path];
|
|
|
|
RefToIDs[&R] = SymRefs.first;
|
|
|
|
F.Refs.insert(&R);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build and store new slabs for each updated file.
|
|
|
|
for (const auto &F : Files) {
|
|
|
|
StringRef Path = F.first();
|
|
|
|
vlog("Update symbols in {0}", Path);
|
|
|
|
SymbolSlab::Builder Syms;
|
|
|
|
RefSlab::Builder Refs;
|
|
|
|
for (const auto *S : F.second.Symbols)
|
|
|
|
Syms.insert(*S);
|
|
|
|
for (const auto *R : F.second.Refs)
|
|
|
|
Refs.insert(RefToIDs[R], *R);
|
|
|
|
|
2018-11-16 17:03:56 +08:00
|
|
|
auto SS = llvm::make_unique<SymbolSlab>(std::move(Syms).build());
|
|
|
|
auto RS = llvm::make_unique<RefSlab>(std::move(Refs).build());
|
2018-12-04 19:31:57 +08:00
|
|
|
auto IG = llvm::make_unique<IncludeGraph>(
|
|
|
|
getSubGraph(URI::create(Path), Index.Sources.getValue()));
|
2018-11-16 17:03:56 +08:00
|
|
|
|
|
|
|
auto Hash = FilesToUpdate.lookup(Path);
|
|
|
|
// We need to store shards before updating the index, since the latter
|
|
|
|
// consumes slabs.
|
|
|
|
if (IndexStorage) {
|
|
|
|
IndexFileOut Shard;
|
|
|
|
Shard.Symbols = SS.get();
|
|
|
|
Shard.Refs = RS.get();
|
2018-12-04 19:31:57 +08:00
|
|
|
Shard.Sources = IG.get();
|
2018-11-28 00:08:53 +08:00
|
|
|
|
2018-11-16 17:03:56 +08:00
|
|
|
if (auto Error = IndexStorage->storeShard(Path, Shard))
|
|
|
|
elog("Failed to write background-index shard for file {0}: {1}", Path,
|
|
|
|
std::move(Error));
|
|
|
|
}
|
|
|
|
|
2018-11-06 18:55:21 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(DigestsMu);
|
|
|
|
// 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.
|
2018-11-16 17:03:56 +08:00
|
|
|
IndexedFileDigests[Path] = Hash;
|
|
|
|
IndexedSymbols.update(Path, std::move(SS), std::move(RS));
|
2018-11-06 18:55:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Creates a filter to not collect index results from files with unchanged
|
|
|
|
// digests.
|
2018-11-16 17:03:56 +08:00
|
|
|
// \p FileDigests contains file digests for the current indexed files, and all
|
|
|
|
// changed files will be added to \p FilesToUpdate.
|
2018-12-04 19:31:57 +08:00
|
|
|
decltype(SymbolCollector::Options::FileFilter)
|
|
|
|
createFileFilter(const llvm::StringMap<FileDigest> &FileDigests,
|
|
|
|
llvm::StringMap<FileDigest> &FilesToUpdate) {
|
2018-11-06 18:55:21 +08:00
|
|
|
return [&FileDigests, &FilesToUpdate](const SourceManager &SM, FileID FID) {
|
|
|
|
StringRef Path;
|
|
|
|
if (const auto *F = SM.getFileEntryForID(FID))
|
|
|
|
Path = F->getName();
|
|
|
|
if (Path.empty())
|
|
|
|
return false; // Skip invalid files.
|
|
|
|
SmallString<128> AbsPath(Path);
|
|
|
|
if (std::error_code EC =
|
|
|
|
SM.getFileManager().getVirtualFileSystem()->makeAbsolute(AbsPath)) {
|
|
|
|
elog("Warning: could not make absolute file: {0}", EC.message());
|
|
|
|
return false; // Skip files without absolute path.
|
|
|
|
}
|
|
|
|
sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true);
|
|
|
|
auto Digest = digestFile(SM, FID);
|
|
|
|
if (!Digest)
|
|
|
|
return false;
|
|
|
|
auto D = FileDigests.find(AbsPath);
|
|
|
|
if (D != FileDigests.end() && D->second == Digest)
|
|
|
|
return false; // Skip files that haven't changed.
|
|
|
|
|
|
|
|
FilesToUpdate[AbsPath] = *Digest;
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-11-16 17:03:56 +08:00
|
|
|
Error BackgroundIndex::index(tooling::CompileCommand Cmd,
|
|
|
|
BackgroundIndexStorage *IndexStorage) {
|
[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);
|
2018-11-15 18:34:39 +08:00
|
|
|
SmallString<128> AbsolutePath;
|
|
|
|
if (sys::path::is_absolute(Cmd.Filename)) {
|
|
|
|
AbsolutePath = Cmd.Filename;
|
|
|
|
} else {
|
|
|
|
AbsolutePath = Cmd.Directory;
|
|
|
|
sys::path::append(AbsolutePath, Cmd.Filename);
|
|
|
|
}
|
[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 FS = FSProvider.getFileSystem();
|
|
|
|
auto Buf = FS->getBufferForFile(AbsolutePath);
|
|
|
|
if (!Buf)
|
|
|
|
return errorCodeToError(Buf.getError());
|
2018-11-06 18:55:21 +08:00
|
|
|
auto Hash = digest(Buf->get()->getBuffer());
|
|
|
|
|
|
|
|
// Take a snapshot of the digests to avoid locking for each file in the TU.
|
|
|
|
llvm::StringMap<FileDigest> DigestsSnapshot;
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> Lock(DigestsMu);
|
|
|
|
if (IndexedFileDigests.lookup(AbsolutePath) == Hash) {
|
|
|
|
vlog("No need to index {0}, already up to date", AbsolutePath);
|
|
|
|
return 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
|
|
|
|
2018-11-06 18:55:21 +08:00
|
|
|
DigestsSnapshot = IndexedFileDigests;
|
[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
|
|
|
}
|
|
|
|
|
|
|
|
log("Indexing {0}", Cmd.Filename, toHex(Hash));
|
|
|
|
ParseInputs Inputs;
|
|
|
|
Inputs.FS = std::move(FS);
|
|
|
|
Inputs.FS->setCurrentWorkingDirectory(Cmd.Directory);
|
|
|
|
Inputs.CompileCommand = std::move(Cmd);
|
|
|
|
auto CI = buildCompilerInvocation(Inputs);
|
|
|
|
if (!CI)
|
2018-10-20 23:30:37 +08:00
|
|
|
return createStringError(inconvertibleErrorCode(),
|
[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
|
|
|
"Couldn't build compiler invocation");
|
|
|
|
IgnoreDiagnostics IgnoreDiags;
|
|
|
|
auto Clang = prepareCompilerInstance(
|
|
|
|
std::move(CI), /*Preamble=*/nullptr, std::move(*Buf),
|
|
|
|
std::make_shared<PCHContainerOperations>(), Inputs.FS, IgnoreDiags);
|
|
|
|
if (!Clang)
|
2018-10-20 23:30:37 +08:00
|
|
|
return createStringError(inconvertibleErrorCode(),
|
[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
|
|
|
"Couldn't build compiler instance");
|
|
|
|
|
|
|
|
SymbolCollector::Options IndexOpts;
|
2018-11-06 18:55:21 +08:00
|
|
|
StringMap<FileDigest> FilesToUpdate;
|
|
|
|
IndexOpts.FileFilter = createFileFilter(DigestsSnapshot, FilesToUpdate);
|
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); },
|
|
|
|
[&](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))
|
2018-10-20 23:30:37 +08:00
|
|
|
return createStringError(inconvertibleErrorCode(),
|
[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
|
|
|
"BeginSourceFile() failed");
|
|
|
|
if (!Action->Execute())
|
2018-10-20 23:30:37 +08:00
|
|
|
return createStringError(inconvertibleErrorCode(), "Execute() failed");
|
[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-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
|
|
|
|
|
|
|
update(AbsolutePath, std::move(Index), FilesToUpdate, IndexStorage);
|
2018-11-06 18:55:21 +08:00
|
|
|
{
|
|
|
|
// Make sure hash for the main file is always updated even if there is no
|
|
|
|
// index data in it.
|
|
|
|
std::lock_guard<std::mutex> Lock(DigestsMu);
|
|
|
|
IndexedFileDigests[AbsolutePath] = 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
|
|
|
|
|
|
|
// FIXME: this should rebuild once-in-a-while, not after every file.
|
|
|
|
// At that point we should use Dex, too.
|
|
|
|
vlog("Rebuilding automatic index");
|
[clangd] Cleanup: stop passing around list of supported URI schemes.
Summary:
Instead of passing around a list of supported URI schemes in clangd, we
expose an interface to convert a path to URI using any compatible scheme
that has been registered. It favors customized schemes and falls
back to "file" when no other scheme works.
Changes in this patch are:
- URI::create(AbsPath, URISchemes) -> URI::create(AbsPath). The new API finds a
compatible scheme from the registry.
- Remove URISchemes option everywhere (ClangdServer, SymbolCollecter, FileIndex etc).
- Unit tests will use "unittest" by default.
- Move "test" scheme from ClangdLSPServer to ClangdMain.cpp, and only
register the test scheme when lit-test or enable-lit-scheme is set.
(The new flag is added to make lit protocol.test work; I wonder if there
is alternative here.)
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits
Differential Revision: https://reviews.llvm.org/D54800
llvm-svn: 347467
2018-11-22 23:02:05 +08:00
|
|
|
reset(IndexedSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge));
|
2018-11-06 18:55:21 +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
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|