summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd')
-rw-r--r--clang-tools-extra/clangd/ClangdLSPServer.cpp11
-rw-r--r--clang-tools-extra/clangd/ClangdLSPServer.h8
-rw-r--r--clang-tools-extra/clangd/ClangdServer.cpp34
-rw-r--r--clang-tools-extra/clangd/ClangdServer.h70
-rw-r--r--clang-tools-extra/clangd/tool/ClangdMain.cpp33
5 files changed, 74 insertions, 82 deletions
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 6e232050ff7..539ee17acf4 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -395,17 +395,12 @@ void ClangdLSPServer::onChangeConfiguration(
}
}
-ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount,
- bool StorePreamblesInMemory,
+ClangdLSPServer::ClangdLSPServer(JSONOutput &Out,
const clangd::CodeCompleteOptions &CCOpts,
- llvm::Optional<StringRef> ResourceDir,
llvm::Optional<Path> CompileCommandsDir,
- bool BuildDynamicSymbolIndex,
- SymbolIndex *StaticIdx)
+ const ClangdServer::Options &Opts)
: Out(Out), CDB(std::move(CompileCommandsDir)), CCOpts(CCOpts),
- Server(CDB, /*DiagConsumer=*/*this, FSProvider, AsyncThreadsCount,
- StorePreamblesInMemory, BuildDynamicSymbolIndex, StaticIdx,
- ResourceDir, /*UpdateDebounce=*/std::chrono::milliseconds(500)) {}
+ Server(CDB, FSProvider, /*DiagConsumer=*/*this, Opts) {}
bool ClangdLSPServer::run(std::istream &In, JSONStreamStyle InputStyle) {
assert(!IsDone && "Run was called before");
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h
index c3c0f80744c..30e174611b7 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -31,13 +31,9 @@ public:
/// If \p CompileCommandsDir has a value, compile_commands.json will be
/// loaded only from \p CompileCommandsDir. Otherwise, clangd will look
/// for compile_commands.json in all parent directories of each file.
- ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount,
- bool StorePreamblesInMemory,
- const clangd::CodeCompleteOptions &CCOpts,
- llvm::Optional<StringRef> ResourceDir,
+ ClangdLSPServer(JSONOutput &Out, const clangd::CodeCompleteOptions &CCOpts,
llvm::Optional<Path> CompileCommandsDir,
- bool BuildDynamicSymbolIndex,
- SymbolIndex *StaticIdx = nullptr);
+ const ClangdServer::Options &Opts);
/// Run LSP server loop, receiving input for it from \p In. \p In must be
/// opened in binary mode. Output will be written using Out variable passed to
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 88b0664d737..db65d5c351f 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -70,37 +70,41 @@ RealFileSystemProvider::getTaggedFileSystem(PathRef File) {
return make_tagged(vfs::getRealFileSystem(), VFSTag());
}
+ClangdServer::Options ClangdServer::optsForTest() {
+ ClangdServer::Options Opts;
+ Opts.UpdateDebounce = std::chrono::steady_clock::duration::zero(); // Faster!
+ Opts.StorePreamblesInMemory = true;
+ Opts.AsyncThreadsCount = 4; // Consistent!
+ return Opts;
+}
+
ClangdServer::ClangdServer(GlobalCompilationDatabase &CDB,
- DiagnosticsConsumer &DiagConsumer,
FileSystemProvider &FSProvider,
- unsigned AsyncThreadsCount,
- bool StorePreamblesInMemory,
- bool BuildDynamicSymbolIndex, SymbolIndex *StaticIdx,
- llvm::Optional<StringRef> ResourceDir,
- std::chrono::steady_clock::duration UpdateDebounce)
- : CompileArgs(CDB,
- ResourceDir ? ResourceDir->str() : getStandardResourceDir()),
+ DiagnosticsConsumer &DiagConsumer,
+ const Options &Opts)
+ : CompileArgs(CDB, Opts.ResourceDir ? Opts.ResourceDir->str()
+ : getStandardResourceDir()),
DiagConsumer(DiagConsumer), FSProvider(FSProvider),
- FileIdx(BuildDynamicSymbolIndex ? new FileIndex() : nullptr),
+ FileIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr),
PCHs(std::make_shared<PCHContainerOperations>()),
// Pass a callback into `WorkScheduler` to extract symbols from a newly
// parsed file and rebuild the file index synchronously each time an AST
// is parsed.
// FIXME(ioeric): this can be slow and we may be able to index on less
// critical paths.
- WorkScheduler(AsyncThreadsCount, StorePreamblesInMemory,
+ WorkScheduler(Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
FileIdx
? [this](PathRef Path,
ParsedAST *AST) { FileIdx->update(Path, AST); }
: ASTParsedCallback(),
- UpdateDebounce) {
- if (FileIdx && StaticIdx) {
- MergedIndex = mergeIndex(FileIdx.get(), StaticIdx);
+ Opts.UpdateDebounce) {
+ if (FileIdx && Opts.StaticIndex) {
+ MergedIndex = mergeIndex(FileIdx.get(), Opts.StaticIndex);
Index = MergedIndex.get();
} else if (FileIdx)
Index = FileIdx.get();
- else if (StaticIdx)
- Index = StaticIdx;
+ else if (Opts.StaticIndex)
+ Index = Opts.StaticIndex;
else
Index = nullptr;
}
diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h
index a443d66229a..5e10c243ed1 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -101,19 +101,36 @@ public:
/// definition.
class ClangdServer {
public:
+ struct Options {
+ /// To process requests asynchronously, ClangdServer spawns worker threads.
+ /// If 0, all requests are processed on the calling thread.
+ unsigned AsyncThreadsCount = getDefaultAsyncThreadsCount();
+
+ /// Cached preambles are potentially large. If false, store them on disk.
+ bool StorePreamblesInMemory = true;
+
+ /// If true, ClangdServer builds a dynamic in-memory index for symbols in
+ /// opened files and uses the index to augment code completion results.
+ bool BuildDynamicSymbolIndex = false;
+
+ /// If set, use this index to augment code completion results.
+ SymbolIndex *StaticIndex = nullptr;
+
+ /// The resource directory is used to find internal headers, overriding
+ /// defaults and -resource-dir compiler flag).
+ /// If None, ClangdServer calls CompilerInvocation::GetResourcePath() to
+ /// obtain the standard resource directory.
+ llvm::Optional<StringRef> ResourceDir = llvm::None;
+
+ /// Time to wait after a new file version before computing diagnostics.
+ std::chrono::steady_clock::duration UpdateDebounce =
+ std::chrono::milliseconds(500);
+ };
+ // Sensible default options for use in tests.
+ // Features like indexing must be enabled if desired.
+ static Options optsForTest();
+
/// Creates a new ClangdServer instance.
- /// To process parsing requests asynchronously, ClangdServer will spawn \p
- /// AsyncThreadsCount worker threads. However, if \p AsyncThreadsCount is 0,
- /// all requests will be processed on the calling thread.
- ///
- /// ClangdServer uses \p FSProvider to get an instance of vfs::FileSystem for
- /// each parsing request. Results of code completion and diagnostics also
- /// include a tag, that \p FSProvider returns along with the vfs::FileSystem.
- ///
- /// The value of \p ResourceDir will be used to search for internal headers
- /// (overriding defaults and -resource-dir compiler flag). If \p ResourceDir
- /// is None, ClangdServer will call CompilerInvocation::GetResourcePath() to
- /// obtain the standard resource directory.
///
/// ClangdServer uses \p CDB to obtain compilation arguments for parsing. Note
/// that ClangdServer only obtains compilation arguments once for each newly
@@ -121,33 +138,16 @@ public:
/// those arguments for subsequent reparses. However, ClangdServer will check
/// if compilation arguments changed on calls to forceReparse().
///
+ /// FSProvider provides a vfs::FileSystem for each parsing request. Results of
+ /// code completion and diagnostics also include a tag, that \p FSProvider
+ /// returns along with the vfs::FileSystem.
+ ///
/// After each parsing request finishes, ClangdServer reports diagnostics to
/// \p DiagConsumer. Note that a callback to \p DiagConsumer happens on a
/// worker thread. Therefore, instances of \p DiagConsumer must properly
/// synchronize access to shared state.
- /// UpdateDebounce determines how long to wait after a new version of the file
- /// before starting to compute diagnostics.
- ///
- /// \p StorePreamblesInMemory defines whether the Preambles generated by
- /// clangd are stored in-memory or on disk.
- ///
- /// If \p BuildDynamicSymbolIndex is true, ClangdServer builds a dynamic
- /// in-memory index for symbols in all opened files and uses the index to
- /// augment code completion results.
- ///
- /// If \p StaticIdx is set, ClangdServer uses the index for global code
- /// completion.
- /// FIXME(sammccall): pull out an options struct.
- ClangdServer(GlobalCompilationDatabase &CDB,
- DiagnosticsConsumer &DiagConsumer,
- FileSystemProvider &FSProvider, unsigned AsyncThreadsCount,
- bool StorePreamblesInMemory,
- bool BuildDynamicSymbolIndex = false,
- SymbolIndex *StaticIdx = nullptr,
- llvm::Optional<StringRef> ResourceDir = llvm::None,
- /* Tiny default debounce, so tests hit the debounce logic */
- std::chrono::steady_clock::duration UpdateDebounce =
- std::chrono::milliseconds(20));
+ ClangdServer(GlobalCompilationDatabase &CDB, FileSystemProvider &FSProvider,
+ DiagnosticsConsumer &DiagConsumer, const Options &Opts);
/// Set the root path of the workspace.
void setRootPath(PathRef RootPath);
diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 00d18185275..4d579b46399 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -188,9 +188,7 @@ int main(int argc, char *argv[]) {
if (Tracer)
TracingSession.emplace(*Tracer);
- llvm::raw_ostream &Outs = llvm::outs();
- llvm::raw_ostream &Logs = llvm::errs();
- JSONOutput Out(Outs, Logs,
+ JSONOutput Out(llvm::outs(), llvm::errs(),
InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,
PrettyPrint);
@@ -199,7 +197,6 @@ int main(int argc, char *argv[]) {
// If --compile-commands-dir arg was invoked, check value and override default
// path.
llvm::Optional<Path> CompileCommandsDirPath;
-
if (CompileCommandsDir.empty()) {
CompileCommandsDirPath = llvm::None;
} else if (!llvm::sys::path::is_absolute(CompileCommandsDir) ||
@@ -212,34 +209,34 @@ int main(int argc, char *argv[]) {
CompileCommandsDirPath = CompileCommandsDir;
}
- bool StorePreamblesInMemory;
+ ClangdServer::Options Opts;
switch (PCHStorage) {
case PCHStorageFlag::Memory:
- StorePreamblesInMemory = true;
+ Opts.StorePreamblesInMemory = true;
break;
case PCHStorageFlag::Disk:
- StorePreamblesInMemory = false;
+ Opts.StorePreamblesInMemory = false;
break;
}
-
- llvm::Optional<StringRef> ResourceDirRef = None;
if (!ResourceDir.empty())
- ResourceDirRef = ResourceDir;
-
- // Change stdin to binary to not lose \r\n on windows.
- llvm::sys::ChangeStdinToBinary();
-
+ Opts.ResourceDir = ResourceDir;
+ Opts.BuildDynamicSymbolIndex = EnableIndexBasedCompletion;
std::unique_ptr<SymbolIndex> StaticIdx;
- if (EnableIndexBasedCompletion && !YamlSymbolFile.empty())
+ if (EnableIndexBasedCompletion && !YamlSymbolFile.empty()) {
StaticIdx = BuildStaticIndex(YamlSymbolFile);
+ Opts.StaticIndex = StaticIdx.get();
+ }
+ Opts.AsyncThreadsCount = WorkerThreadsCount;
+
clangd::CodeCompleteOptions CCOpts;
CCOpts.IncludeIneligibleResults = IncludeIneligibleResults;
CCOpts.Limit = LimitCompletionResult;
+
// Initialize and run ClangdLSPServer.
- ClangdLSPServer LSPServer(Out, WorkerThreadsCount, StorePreamblesInMemory,
- CCOpts, ResourceDirRef, CompileCommandsDirPath,
- EnableIndexBasedCompletion, StaticIdx.get());
+ ClangdLSPServer LSPServer(Out, CCOpts, CompileCommandsDirPath, Opts);
constexpr int NoShutdownRequestErrorCode = 1;
llvm::set_thread_name("clangd.main");
+ // Change stdin to binary to not lose \r\n on windows.
+ llvm::sys::ChangeStdinToBinary();
return LSPServer.run(std::cin, InputStyle) ? 0 : NoShutdownRequestErrorCode;
}
OpenPOWER on IntegriCloud