[clangd] Wait for compile command in ASTWorker instead of ClangdServer

Summary:
This makes addDocument non-blocking and would also allow code completion
(in fallback mode) to run when worker waits for the compile command.

Reviewers: sammccall, ilya-biryukov

Reviewed By: ilya-biryukov

Subscribers: javed.absar, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D60607

llvm-svn: 358400
This commit is contained in:
Eric Liu 2019-04-15 12:32:28 +00:00
parent 2be3f868f9
commit 9ef03dd20a
9 changed files with 194 additions and 102 deletions

View File

@ -109,7 +109,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
const FileSystemProvider &FSProvider,
DiagnosticsConsumer &DiagConsumer,
const Options &Opts)
: CDB(CDB), FSProvider(FSProvider),
: FSProvider(FSProvider),
DynamicIdx(Opts.BuildDynamicSymbolIndex
? new FileIndex(Opts.HeavyweightDynamicSymbolIndex)
: nullptr),
@ -121,7 +121,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
// is parsed.
// FIXME(ioeric): this can be slow and we may be able to index on less
// critical paths.
WorkScheduler(Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
WorkScheduler(CDB, Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
llvm::make_unique<UpdateIndexCallbacks>(DynamicIdx.get(),
DiagConsumer),
Opts.UpdateDebounce, Opts.RetentionPolicy) {
@ -155,12 +155,8 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
Opts.ClangTidyOpts = ClangTidyOptProvider->getOptions(File);
Opts.SuggestMissingIncludes = SuggestMissingIncludes;
// FIXME: some build systems like Bazel will take time to preparing
// environment to build the file, it would be nice if we could emit a
// "PreparingBuild" status to inform users, it is non-trivial given the
// current implementation.
// Compile command is set asynchronously during update, as it can be slow.
ParseInputs Inputs;
Inputs.CompileCommand = getCompileCommand(File);
Inputs.FS = FSProvider.getFileSystem();
Inputs.Contents = Contents;
Inputs.Opts = std::move(Opts);
@ -543,14 +539,6 @@ void ClangdServer::typeHierarchy(PathRef File, Position Pos, int Resolve,
WorkScheduler.runWithAST("Type Hierarchy", File, Bind(Action, std::move(CB)));
}
tooling::CompileCommand ClangdServer::getCompileCommand(PathRef File) {
trace::Span Span("GetCompileCommand");
llvm::Optional<tooling::CompileCommand> C = CDB.getCompileCommand(File);
if (!C) // FIXME: Suppress diagnostics? Let the user know?
C = CDB.getFallbackCommand(File);
return std::move(*C);
}
void ClangdServer::onFileEvent(const DidChangeWatchedFilesParams &Params) {
// FIXME: Do nothing for now. This will be used for indexing and potentially
// invalidating other caches.

View File

@ -266,9 +266,6 @@ private:
formatCode(llvm::StringRef Code, PathRef File,
ArrayRef<tooling::Range> Ranges);
tooling::CompileCommand getCompileCommand(PathRef File);
const GlobalCompilationDatabase &CDB;
const FileSystemProvider &FSProvider;
Path ResourceDir;

View File

@ -16,9 +16,9 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILER_H
#include "../clang-tidy/ClangTidyOptions.h"
#include "GlobalCompilationDatabase.h"
#include "index/Index.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/PrecompiledPreamble.h"
#include "clang/Tooling/CompilationDatabase.h"

View File

@ -63,10 +63,11 @@ GlobalCompilationDatabase::getFallbackCommand(PathRef File) const {
if (llvm::sys::path::extension(File) == ".h")
Argv.push_back("-xobjective-c++-header");
Argv.push_back(File);
return tooling::CompileCommand(llvm::sys::path::parent_path(File),
llvm::sys::path::filename(File),
std::move(Argv),
/*Output=*/"");
tooling::CompileCommand Cmd(llvm::sys::path::parent_path(File),
llvm::sys::path::filename(File), std::move(Argv),
/*Output=*/"");
Cmd.Heuristic = "clangd fallback";
return Cmd;
}
DirectoryBasedGlobalCompilationDatabase::

View File

@ -43,10 +43,13 @@
#include "TUScheduler.h"
#include "Cancellation.h"
#include "Compiler.h"
#include "GlobalCompilationDatabase.h"
#include "Logger.h"
#include "Trace.h"
#include "index/CanonicalIncludes.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/Errc.h"
@ -154,10 +157,10 @@ class ASTWorkerHandle;
/// worker.
class ASTWorker {
friend class ASTWorkerHandle;
ASTWorker(PathRef FileName, TUScheduler::ASTCache &LRUCache,
Semaphore &Barrier, bool RunSync,
steady_clock::duration UpdateDebounce,
bool StorePreamblesInMemory, ParsingCallbacks &Callbacks);
ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
TUScheduler::ASTCache &LRUCache, Semaphore &Barrier, bool RunSync,
steady_clock::duration UpdateDebounce, bool StorePreamblesInMemory,
ParsingCallbacks &Callbacks);
public:
/// Create a new ASTWorker and return a handle to it.
@ -165,12 +168,11 @@ public:
/// is null, all requests will be processed on the calling thread
/// synchronously instead. \p Barrier is acquired when processing each
/// request, it is used to limit the number of actively running threads.
static ASTWorkerHandle create(PathRef FileName,
TUScheduler::ASTCache &IdleASTs,
AsyncTaskRunner *Tasks, Semaphore &Barrier,
steady_clock::duration UpdateDebounce,
bool StorePreamblesInMemory,
ParsingCallbacks &Callbacks);
static ASTWorkerHandle
create(PathRef FileName, const GlobalCompilationDatabase &CDB,
TUScheduler::ASTCache &IdleASTs, AsyncTaskRunner *Tasks,
Semaphore &Barrier, steady_clock::duration UpdateDebounce,
bool StorePreamblesInMemory, ParsingCallbacks &Callbacks);
~ASTWorker();
void update(ParseInputs Inputs, WantDiagnostics);
@ -185,6 +187,9 @@ public:
/// It may be delivered immediately, or later on the worker thread.
void getCurrentPreamble(
llvm::unique_function<void(std::shared_ptr<const PreambleData>)>);
/// Returns compile command from the current file inputs.
tooling::CompileCommand getCurrentCompileCommand() const;
/// Wait for the first build of preamble to finish. Preamble itself can be
/// accessed via getPossiblyStalePreamble(). Note that this function will
/// return after an unsuccessful build of the preamble too, i.e. result of
@ -215,6 +220,10 @@ private:
Deadline scheduleLocked();
/// Should the first task in the queue be skipped instead of run?
bool shouldSkipHeadLocked() const;
/// This is private because `FileInputs.FS` is not thread-safe and thus not
/// safe to share. Callers should make sure not to expose `FS` via a public
/// interface.
std::shared_ptr<const ParseInputs> getCurrentFileInputs() const;
struct Request {
llvm::unique_function<void()> Action;
@ -231,6 +240,7 @@ private:
const steady_clock::duration UpdateDebounce;
/// File that ASTWorker is responsible for.
const Path FileName;
const GlobalCompilationDatabase &CDB;
/// Whether to keep the built preambles in memory or on disk.
const bool StorePreambleInMemory;
/// Callback invoked when preamble or main file AST is built.
@ -239,13 +249,15 @@ private:
TUStatus Status;
Semaphore &Barrier;
/// Inputs, corresponding to the current state of AST.
ParseInputs FileInputs;
/// Whether the diagnostics for the current FileInputs were reported to the
/// users before.
bool DiagsWereReported = false;
/// Guards members used by both TUScheduler and the worker thread.
mutable std::mutex Mutex;
/// File inputs, currently being used by the worker.
/// Inputs are written and read by the worker thread, compile command can also
/// be consumed by clients of ASTWorker.
std::shared_ptr<const ParseInputs> FileInputs; /* GUARDED_BY(Mutex) */
std::shared_ptr<const PreambleData> LastBuiltPreamble; /* GUARDED_BY(Mutex) */
/// Becomes ready when the first preamble build finishes.
Notification PreambleWasBuilt;
@ -306,14 +318,13 @@ private:
std::shared_ptr<ASTWorker> Worker;
};
ASTWorkerHandle ASTWorker::create(PathRef FileName,
TUScheduler::ASTCache &IdleASTs,
AsyncTaskRunner *Tasks, Semaphore &Barrier,
steady_clock::duration UpdateDebounce,
bool StorePreamblesInMemory,
ParsingCallbacks &Callbacks) {
ASTWorkerHandle
ASTWorker::create(PathRef FileName, const GlobalCompilationDatabase &CDB,
TUScheduler::ASTCache &IdleASTs, AsyncTaskRunner *Tasks,
Semaphore &Barrier, steady_clock::duration UpdateDebounce,
bool StorePreamblesInMemory, ParsingCallbacks &Callbacks) {
std::shared_ptr<ASTWorker> Worker(
new ASTWorker(FileName, IdleASTs, Barrier, /*RunSync=*/!Tasks,
new ASTWorker(FileName, CDB, IdleASTs, Barrier, /*RunSync=*/!Tasks,
UpdateDebounce, StorePreamblesInMemory, Callbacks));
if (Tasks)
Tasks->runAsync("worker:" + llvm::sys::path::filename(FileName),
@ -322,15 +333,23 @@ ASTWorkerHandle ASTWorker::create(PathRef FileName,
return ASTWorkerHandle(std::move(Worker));
}
ASTWorker::ASTWorker(PathRef FileName, TUScheduler::ASTCache &LRUCache,
Semaphore &Barrier, bool RunSync,
steady_clock::duration UpdateDebounce,
ASTWorker::ASTWorker(PathRef FileName, const GlobalCompilationDatabase &CDB,
TUScheduler::ASTCache &LRUCache, Semaphore &Barrier,
bool RunSync, steady_clock::duration UpdateDebounce,
bool StorePreamblesInMemory, ParsingCallbacks &Callbacks)
: IdleASTs(LRUCache), RunSync(RunSync), UpdateDebounce(UpdateDebounce),
FileName(FileName), StorePreambleInMemory(StorePreamblesInMemory),
FileName(FileName), CDB(CDB),
StorePreambleInMemory(StorePreamblesInMemory),
Callbacks(Callbacks), Status{TUAction(TUAction::Idle, ""),
TUStatus::BuildDetails()},
Barrier(Barrier), Done(false) {}
Barrier(Barrier), Done(false) {
auto Inputs = std::make_shared<ParseInputs>();
// Set a fallback command because compile command can be accessed before
// `Inputs` is initialized. Other fields are only used after initialization
// from client inputs.
Inputs->CompileCommand = CDB.getFallbackCommand(FileName);
FileInputs = std::move(Inputs);
}
ASTWorker::~ASTWorker() {
// Make sure we remove the cached AST, if any.
@ -345,14 +364,28 @@ ASTWorker::~ASTWorker() {
void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags) {
llvm::StringRef TaskName = "Update";
auto Task = [=]() mutable {
// Get the actual command as `Inputs` does not have a command.
// FIXME: some build systems like Bazel will take time to preparing
// environment to build the file, it would be nice if we could emit a
// "PreparingBuild" status to inform users, it is non-trivial given the
// current implementation.
if (auto Cmd = CDB.getCompileCommand(FileName))
Inputs.CompileCommand = *Cmd;
else
// FIXME: consider using old command if it's not a fallback one.
Inputs.CompileCommand = CDB.getFallbackCommand(FileName);
auto PrevInputs = getCurrentFileInputs();
// Will be used to check if we can avoid rebuilding the AST.
bool InputsAreTheSame =
std::tie(FileInputs.CompileCommand, FileInputs.Contents) ==
std::tie(PrevInputs->CompileCommand, PrevInputs->Contents) ==
std::tie(Inputs.CompileCommand, Inputs.Contents);
tooling::CompileCommand OldCommand = std::move(FileInputs.CompileCommand);
tooling::CompileCommand OldCommand = PrevInputs->CompileCommand;
bool PrevDiagsWereReported = DiagsWereReported;
FileInputs = Inputs;
{
std::lock_guard<std::mutex> Lock(Mutex);
FileInputs = std::make_shared<ParseInputs>(Inputs);
}
DiagsWereReported = false;
emitTUStatus({TUAction::BuildingPreamble, TaskName});
log("Updating file {0} with command {1}\n[{2}]\n{3}", FileName,
@ -475,15 +508,16 @@ void ASTWorker::runWithAST(
if (isCancelled())
return Action(llvm::make_error<CancelledError>());
llvm::Optional<std::unique_ptr<ParsedAST>> AST = IdleASTs.take(this);
auto CurrentInputs = getCurrentFileInputs();
if (!AST) {
std::unique_ptr<CompilerInvocation> Invocation =
buildCompilerInvocation(FileInputs);
buildCompilerInvocation(*CurrentInputs);
// Try rebuilding the AST.
llvm::Optional<ParsedAST> NewAST =
Invocation
? buildAST(FileName,
llvm::make_unique<CompilerInvocation>(*Invocation),
FileInputs, getPossiblyStalePreamble())
*CurrentInputs, getPossiblyStalePreamble())
: None;
AST = NewAST ? llvm::make_unique<ParsedAST>(std::move(*NewAST)) : nullptr;
}
@ -494,7 +528,7 @@ void ASTWorker::runWithAST(
if (!*AST)
return Action(llvm::make_error<llvm::StringError>(
"invalid AST", llvm::errc::invalid_argument));
Action(InputsAndAST{FileInputs, **AST});
Action(InputsAndAST{*CurrentInputs, **AST});
};
startTask(Name, Bind(Task, std::move(Action)),
/*UpdateType=*/None);
@ -536,6 +570,16 @@ void ASTWorker::getCurrentPreamble(
void ASTWorker::waitForFirstPreamble() const { PreambleWasBuilt.wait(); }
std::shared_ptr<const ParseInputs> ASTWorker::getCurrentFileInputs() const {
std::unique_lock<std::mutex> Lock(Mutex);
return FileInputs;
}
tooling::CompileCommand ASTWorker::getCurrentCompileCommand() const {
std::unique_lock<std::mutex> Lock(Mutex);
return FileInputs->CompileCommand;
}
std::size_t ASTWorker::getUsedBytes() const {
// Note that we don't report the size of ASTs currently used for processing
// the in-flight requests. We used this information for debugging purposes
@ -774,16 +818,16 @@ FileStatus TUStatus::render(PathRef File) const {
struct TUScheduler::FileData {
/// Latest inputs, passed to TUScheduler::update().
std::string Contents;
tooling::CompileCommand Command;
ASTWorkerHandle Worker;
};
TUScheduler::TUScheduler(unsigned AsyncThreadsCount,
TUScheduler::TUScheduler(const GlobalCompilationDatabase &CDB,
unsigned AsyncThreadsCount,
bool StorePreamblesInMemory,
std::unique_ptr<ParsingCallbacks> Callbacks,
std::chrono::steady_clock::duration UpdateDebounce,
ASTRetentionPolicy RetentionPolicy)
: StorePreamblesInMemory(StorePreamblesInMemory),
: CDB(CDB), StorePreamblesInMemory(StorePreamblesInMemory),
Callbacks(Callbacks ? move(Callbacks)
: llvm::make_unique<ParsingCallbacks>()),
Barrier(AsyncThreadsCount),
@ -822,13 +866,13 @@ void TUScheduler::update(PathRef File, ParseInputs Inputs,
if (!FD) {
// Create a new worker to process the AST-related tasks.
ASTWorkerHandle Worker = ASTWorker::create(
File, *IdleASTs, WorkerThreads ? WorkerThreads.getPointer() : nullptr,
Barrier, UpdateDebounce, StorePreamblesInMemory, *Callbacks);
FD = std::unique_ptr<FileData>(new FileData{
Inputs.Contents, Inputs.CompileCommand, std::move(Worker)});
File, CDB, *IdleASTs,
WorkerThreads ? WorkerThreads.getPointer() : nullptr, Barrier,
UpdateDebounce, StorePreamblesInMemory, *Callbacks);
FD = std::unique_ptr<FileData>(
new FileData{Inputs.Contents, std::move(Worker)});
} else {
FD->Contents = Inputs.Contents;
FD->Command = Inputs.CompileCommand;
}
FD->Worker->update(std::move(Inputs), WantDiags);
}
@ -876,7 +920,8 @@ void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File,
SPAN_ATTACH(Tracer, "file", File);
std::shared_ptr<const PreambleData> Preamble =
It->second->Worker->getPossiblyStalePreamble();
Action(InputsAndPreamble{It->second->Contents, It->second->Command,
Action(InputsAndPreamble{It->second->Contents,
It->second->Worker->getCurrentCompileCommand(),
Preamble.get()});
return;
}
@ -923,7 +968,7 @@ void TUScheduler::runWithPreamble(llvm::StringRef Name, PathRef File,
PreambleTasks->runAsync(
"task:" + llvm::sys::path::filename(File),
Bind(Task, std::string(Name), std::string(File), It->second->Contents,
It->second->Command,
Worker->getCurrentCompileCommand(),
Context::current().derive(kFileBeingProcessed, File),
std::move(ConsistentPreamble), std::move(Action)));
}

View File

@ -11,6 +11,7 @@
#include "ClangdUnit.h"
#include "Function.h"
#include "GlobalCompilationDatabase.h"
#include "Threading.h"
#include "index/CanonicalIncludes.h"
#include "llvm/ADT/Optional.h"
@ -125,7 +126,8 @@ public:
/// FIXME(sammccall): pull out a scheduler options struct.
class TUScheduler {
public:
TUScheduler(unsigned AsyncThreadsCount, bool StorePreamblesInMemory,
TUScheduler(const GlobalCompilationDatabase &CDB, unsigned AsyncThreadsCount,
bool StorePreamblesInMemory,
std::unique_ptr<ParsingCallbacks> ASTCallbacks,
std::chrono::steady_clock::duration UpdateDebounce,
ASTRetentionPolicy RetentionPolicy);
@ -141,10 +143,11 @@ public:
std::vector<Path> getFilesWithCachedAST() const;
/// Schedule an update for \p File. Adds \p File to a list of tracked files if
/// \p File was not part of it before.
/// If diagnostics are requested (Yes), and the context is cancelled before
/// they are prepared, they may be skipped if eventual-consistency permits it
/// (i.e. WantDiagnostics is downgraded to Auto).
/// \p File was not part of it before. The compile command in \p Inputs is
/// ignored; worker queries CDB to get the actual compile command.
/// If diagnostics are requested (Yes), and the context is cancelled
/// before they are prepared, they may be skipped if eventual-consistency
/// permits it (i.e. WantDiagnostics is downgraded to Auto).
void update(PathRef File, ParseInputs Inputs, WantDiagnostics WD);
/// Remove \p File from the list of tracked files and schedule removal of its
@ -217,6 +220,7 @@ public:
static llvm::Optional<llvm::StringRef> getFileBeingProcessedInContext();
private:
const GlobalCompilationDatabase &CDB;
const bool StorePreamblesInMemory;
std::unique_ptr<ParsingCallbacks> Callbacks; // not nullptr
Semaphore Barrier;

View File

@ -1099,6 +1099,64 @@ TEST_F(ClangdVFSTest, FallbackWhenPreambleIsNotReady) {
Field(&CodeCompletion::Scope, "ns::"))));
}
TEST_F(ClangdVFSTest, FallbackWhenWaitingForCompileCommand) {
MockFSProvider FS;
ErrorCheckingDiagConsumer DiagConsumer;
// Returns compile command only when notified.
class DelayedCompilationDatabase : public GlobalCompilationDatabase {
public:
DelayedCompilationDatabase(Notification &CanReturnCommand)
: CanReturnCommand(CanReturnCommand) {}
llvm::Optional<tooling::CompileCommand>
getCompileCommand(PathRef File, ProjectInfo * = nullptr) const override {
// FIXME: make this timeout and fail instead of waiting forever in case
// something goes wrong.
CanReturnCommand.wait();
auto FileName = llvm::sys::path::filename(File);
std::vector<std::string> CommandLine = {"clangd", "-ffreestanding", File};
return {tooling::CompileCommand(llvm::sys::path::parent_path(File),
FileName, std::move(CommandLine), "")};
}
std::vector<std::string> ExtraClangFlags;
private:
Notification &CanReturnCommand;
};
Notification CanReturnCommand;
DelayedCompilationDatabase CDB(CanReturnCommand);
ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
auto FooCpp = testPath("foo.cpp");
Annotations Code(R"cpp(
namespace ns { int xyz; }
using namespace ns;
int main() {
xy^
})cpp");
FS.Files[FooCpp] = FooCpp;
Server.addDocument(FooCpp, Code.code());
// Sleep for some time to make sure code completion is not run because update
// hasn't been scheduled.
std::this_thread::sleep_for(std::chrono::milliseconds(10));
auto Opts = clangd::CodeCompleteOptions();
Opts.AllowFallback = true;
auto Res = cantFail(runCodeComplete(Server, FooCpp, Code.point(), Opts));
EXPECT_EQ(Res.Context, CodeCompletionContext::CCC_Recovery);
CanReturnCommand.notify();
ASSERT_TRUE(Server.blockUntilIdleForTest());
EXPECT_THAT(cantFail(runCodeComplete(Server, FooCpp, Code.point(),
clangd::CodeCompleteOptions()))
.Completions,
ElementsAre(AllOf(Field(&CodeCompletion::Name, "xyz"),
Field(&CodeCompletion::Scope, "ns::"))));
}
} // namespace
} // namespace clangd
} // namespace clang

View File

@ -1386,7 +1386,7 @@ TEST(CompletionTest, NonDocComments) {
// FIXME: Auto-completion in a template requires disabling delayed template
// parsing.
CDB.ExtraClangFlags.push_back("-fno-delayed-template-parsing");
Server.addDocument(FooCpp, Source.code(), WantDiagnostics::Yes);
runAddDocument(Server, FooCpp, Source.code(), WantDiagnostics::Yes);
CodeCompleteResult Completions = cantFail(runCodeComplete(
Server, FooCpp, Source.point(), clangd::CodeCompleteOptions()));

View File

@ -21,8 +21,6 @@ namespace clang {
namespace clangd {
namespace {
using ::testing::_;
using ::testing::AllOf;
using ::testing::AnyOf;
using ::testing::Each;
using ::testing::ElementsAre;
@ -103,7 +101,7 @@ Key<llvm::unique_function<void(PathRef File, std::vector<Diag>)>>
TUSchedulerTests::DiagsCallbackKey;
TEST_F(TUSchedulerTests, MissingFiles) {
TUScheduler S(getDefaultAsyncThreadsCount(),
TUScheduler S(CDB, getDefaultAsyncThreadsCount(),
/*StorePreamblesInMemory=*/true, /*ASTCallbacks=*/nullptr,
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
@ -154,7 +152,7 @@ TEST_F(TUSchedulerTests, WantDiagnostics) {
// thread until we've scheduled them all.
Notification Ready;
TUScheduler S(
getDefaultAsyncThreadsCount(),
CDB, getDefaultAsyncThreadsCount(),
/*StorePreamblesInMemory=*/true, captureDiags(),
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
@ -184,7 +182,7 @@ TEST_F(TUSchedulerTests, WantDiagnostics) {
TEST_F(TUSchedulerTests, Debounce) {
std::atomic<int> CallbackCount(0);
{
TUScheduler S(getDefaultAsyncThreadsCount(),
TUScheduler S(CDB, getDefaultAsyncThreadsCount(),
/*StorePreamblesInMemory=*/true, captureDiags(),
/*UpdateDebounce=*/std::chrono::seconds(1),
ASTRetentionPolicy());
@ -220,7 +218,7 @@ TEST_F(TUSchedulerTests, PreambleConsistency) {
{
Notification InconsistentReadDone; // Must live longest.
TUScheduler S(
getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true,
CDB, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true,
/*ASTCallbacks=*/nullptr,
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
@ -277,7 +275,7 @@ TEST_F(TUSchedulerTests, Cancellation) {
{
Notification Proceed; // Ensure we schedule everything.
TUScheduler S(
getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true,
CDB, getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true,
/*ASTCallbacks=*/captureDiags(),
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
@ -346,7 +344,7 @@ TEST_F(TUSchedulerTests, ManyUpdates) {
// Run TUScheduler and collect some stats.
{
TUScheduler S(getDefaultAsyncThreadsCount(),
TUScheduler S(CDB, getDefaultAsyncThreadsCount(),
/*StorePreamblesInMemory=*/true, captureDiags(),
/*UpdateDebounce=*/std::chrono::milliseconds(50),
ASTRetentionPolicy());
@ -437,10 +435,11 @@ TEST_F(TUSchedulerTests, EvictedAST) {
std::atomic<int> BuiltASTCounter(0);
ASTRetentionPolicy Policy;
Policy.MaxRetainedASTs = 2;
TUScheduler S(
/*AsyncThreadsCount=*/1, /*StorePreambleInMemory=*/true,
/*ASTCallbacks=*/nullptr,
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(), Policy);
TUScheduler S(CDB,
/*AsyncThreadsCount=*/1, /*StorePreambleInMemory=*/true,
/*ASTCallbacks=*/nullptr,
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
Policy);
llvm::StringLiteral SourceContents = R"cpp(
int* a;
@ -487,11 +486,11 @@ TEST_F(TUSchedulerTests, EvictedAST) {
}
TEST_F(TUSchedulerTests, EmptyPreamble) {
TUScheduler S(
/*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true,
/*ASTCallbacks=*/nullptr,
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
TUScheduler S(CDB,
/*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true,
/*ASTCallbacks=*/nullptr,
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
auto Foo = testPath("foo.cpp");
auto Header = testPath("foo.h");
@ -532,11 +531,11 @@ TEST_F(TUSchedulerTests, EmptyPreamble) {
TEST_F(TUSchedulerTests, RunWaitsForPreamble) {
// Testing strategy: we update the file and schedule a few preamble reads at
// the same time. All reads should get the same non-null preamble.
TUScheduler S(
/*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true,
/*ASTCallbacks=*/nullptr,
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
TUScheduler S(CDB,
/*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true,
/*ASTCallbacks=*/nullptr,
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
auto Foo = testPath("foo.cpp");
auto NonEmptyPreamble = R"cpp(
#define FOO 1
@ -564,11 +563,11 @@ TEST_F(TUSchedulerTests, RunWaitsForPreamble) {
}
TEST_F(TUSchedulerTests, NoopOnEmptyChanges) {
TUScheduler S(
/*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
/*StorePreambleInMemory=*/true, captureDiags(),
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
TUScheduler S(CDB,
/*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
/*StorePreambleInMemory=*/true, captureDiags(),
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
auto Source = testPath("foo.cpp");
auto Header = testPath("foo.h");
@ -617,11 +616,11 @@ TEST_F(TUSchedulerTests, NoopOnEmptyChanges) {
}
TEST_F(TUSchedulerTests, NoChangeDiags) {
TUScheduler S(
/*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
/*StorePreambleInMemory=*/true, captureDiags(),
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
TUScheduler S(CDB,
/*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
/*StorePreambleInMemory=*/true, captureDiags(),
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());
auto FooCpp = testPath("foo.cpp");
auto Contents = "int a; int b;";
@ -652,7 +651,7 @@ TEST_F(TUSchedulerTests, NoChangeDiags) {
}
TEST_F(TUSchedulerTests, Run) {
TUScheduler S(/*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
TUScheduler S(CDB, /*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(),
/*StorePreambleInMemory=*/true, /*ASTCallbacks=*/nullptr,
/*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(),
ASTRetentionPolicy());