10 #include "Features.inc" 16 #include "clang/Basic/Version.h" 17 #include "llvm/Support/CommandLine.h" 18 #include "llvm/Support/FileSystem.h" 19 #include "llvm/Support/Path.h" 20 #include "llvm/Support/Program.h" 21 #include "llvm/Support/Signals.h" 22 #include "llvm/Support/raw_ostream.h" 32 static llvm::cl::opt<bool>
34 llvm::cl::desc(
"Use experimental Dex dynamic index."),
35 llvm::cl::init(
false), llvm::cl::Hidden);
38 "compile-commands-dir",
39 llvm::cl::desc(
"Specify a path to look for compile_commands.json. If path " 40 "is invalid, clangd will look in the current directory and " 41 "parent paths of each source file."));
43 static llvm::cl::opt<unsigned>
45 llvm::cl::desc(
"Number of async workers used by clangd"),
52 llvm::cl::desc(
"Granularity of code completion suggestions"),
55 "One completion item for each semantically distinct " 56 "completion, with full type information."),
57 clEnumValN(Bundled,
"bundled",
58 "Similar completion items (e.g. function overloads) are " 59 "combined. Type information shown where possible.")),
65 "include-ineligible-results",
67 "Include ineligible completion results (e.g. private members)"),
71 static llvm::cl::opt<JSONStreamStyle>
InputStyle(
72 "input-style", llvm::cl::desc(
"Input JSON stream encoding"),
76 "messages delimited by --- lines, with # comment support")),
79 static llvm::cl::opt<bool>
80 PrettyPrint(
"pretty", llvm::cl::desc(
"Pretty-print JSON output"),
81 llvm::cl::init(
false));
83 static llvm::cl::opt<Logger::Level>
LogLevel(
84 "log", llvm::cl::desc(
"Verbosity of log messages written to stderr"),
85 llvm::cl::values(clEnumValN(
Logger::Error,
"error",
"Error messages only"),
87 "High level execution tracing"),
91 static llvm::cl::opt<bool>
93 llvm::cl::desc(
"Abbreviation for -input-style=delimited -pretty " 94 "-run-synchronously -enable-test-scheme. " 95 "Intended to simplify lit tests."),
96 llvm::cl::init(
false), llvm::cl::Hidden);
99 "enable-test-uri-scheme",
100 llvm::cl::desc(
"Enable 'test:' URI scheme. Only use in lit tests."),
101 llvm::cl::init(
false), llvm::cl::Hidden);
104 static llvm::cl::opt<PCHStorageFlag>
PCHStorage(
106 llvm::cl::desc(
"Storing PCHs in memory increases memory usages, but may " 107 "improve performance"),
115 llvm::cl::desc(
"Limit the number of results returned by clangd. " 116 "0 means no limit."),
117 llvm::cl::init(100));
121 llvm::cl::desc(
"Parse on main thread. If set, -j is ignored"),
122 llvm::cl::init(
false), llvm::cl::Hidden);
124 static llvm::cl::opt<Path>
126 llvm::cl::desc(
"Directory for system clang headers"),
127 llvm::cl::init(
""), llvm::cl::Hidden);
132 "Mirror all LSP input to the specified file. Useful for debugging."),
133 llvm::cl::init(
""), llvm::cl::Hidden);
138 "Enable index-based features. By default, clangd maintains an index " 139 "built from symbols in opened files. Global index support needs to " 140 "enabled separatedly."),
141 llvm::cl::init(
true), llvm::cl::Hidden);
144 "all-scopes-completion",
146 "If set to true, code completion will include index symbols that are " 147 "not defined in the scopes (e.g. " 148 "namespaces) visible from the code completion point. Such completions " 149 "can insert scope qualifiers."),
150 llvm::cl::init(
true));
153 "debug-origin", llvm::cl::desc(
"Show origins of completion items"),
157 "header-insertion-decorators",
158 llvm::cl::desc(
"Prepend a circular dot or space before the completion " 159 "label, depending on whether " 160 "an include line will be inserted or not."),
161 llvm::cl::init(
true));
166 "Index file to build the static index. The file must have been created " 167 "by a compatible clangd-index.\n" 168 "WARNING: This option is experimental only, and will be removed " 169 "eventually. Don't rely on it."),
170 llvm::cl::init(
""), llvm::cl::Hidden);
175 "Index project code in the background and persist index on disk. " 177 llvm::cl::init(
false), llvm::cl::Hidden);
180 "background-index-rebuild-period",
182 "If set to non-zero, the background index rebuilds the symbol index " 183 "periodically every X milliseconds; otherwise, the " 184 "symbol index will be updated for each indexed file."),
185 llvm::cl::init(5000), llvm::cl::Hidden);
189 "compile_args_from", llvm::cl::desc(
"The source of compile commands"),
191 "All compile commands come from LSP and " 192 "'compile_commands.json' files are ignored"),
193 clEnumValN(FilesystemCompileArgs,
"filesystem",
194 "All compile commands come from the " 195 "'compile_commands.json' files")),
196 llvm::cl::init(FilesystemCompileArgs), llvm::cl::Hidden);
199 "function-arg-placeholders",
200 llvm::cl::desc(
"When disabled, completions contain only parentheses for " 201 "function calls. When enabled, completions also contain " 202 "placeholders for method parameters."),
213 llvm::Expected<std::string>
214 getAbsolutePath(llvm::StringRef , llvm::StringRef Body,
215 llvm::StringRef )
const override {
216 using namespace llvm::sys;
219 if (!Body.startswith(
"/"))
220 return llvm::make_error<llvm::StringError>(
221 "Expect URI body to be an absolute path starting with '/': " + Body,
222 llvm::inconvertibleErrorCode());
223 Body = Body.ltrim(
'/');
224 llvm::SmallVector<char, 16>
Path(Body.begin(), Body.end());
227 return std::string(
Path.begin(),
Path.end());
231 uriFromAbsolutePath(llvm::StringRef AbsolutePath)
const override {
232 llvm::StringRef Body = AbsolutePath;
233 if (!Body.consume_front(TestScheme::TestDir)) {
234 return llvm::make_error<llvm::StringError>(
235 "Path " + AbsolutePath +
" doesn't start with root " + TestDir,
236 llvm::inconvertibleErrorCode());
239 return URI(
"test",
"",
240 llvm::sys::path::convert_to_slash(Body));
244 const static char TestDir[];
248 const char TestScheme::TestDir[] =
"C:\\clangd-test";
250 const char TestScheme::TestDir[] =
"/clangd-test";
262 int main(
int argc,
char *argv[]) {
263 using namespace clang;
266 llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
267 llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
268 OS << clang::getClangToolFullVersion(
"clangd") <<
"\n";
270 llvm::cl::ParseCommandLineOptions(
272 "clangd is a language server that provides IDE-like features to editors. " 273 "\n\nIt should be used via an editor plugin rather than invoked " 275 "For more information, see:" 276 "\n\thttps://clang.llvm.org/extra/clangd.html" 277 "\n\thttps://microsoft.github.io/language-server-protocol/");
285 static URISchemeRegistry::Add<TestScheme>
X(
286 "test",
"Test scheme for clangd lit tests.");
290 llvm::errs() <<
"A number of worker threads cannot be 0. Did you mean to " 291 "specify -run-synchronously?";
297 llvm::errs() <<
"Ignoring -j because -run-synchronously is set.\n";
302 llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
306 llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
308 InputMirrorStream.reset();
309 llvm::errs() <<
"Error while opening an input mirror file: " 312 InputMirrorStream->SetUnbuffered();
319 llvm::Optional<llvm::raw_fd_ostream> TraceStream;
320 std::unique_ptr<trace::EventTracer> Tracer;
321 if (
auto *TraceFile = getenv(
"CLANGD_TRACE")) {
323 TraceStream.emplace(TraceFile, EC,
324 llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
327 llvm::errs() <<
"Error while opening trace file " << TraceFile <<
": " 334 llvm::Optional<trace::Session> TracingSession;
336 TracingSession.emplace(*Tracer);
340 llvm::errs().SetBuffered();
346 llvm::Optional<Path> CompileCommandsDirPath;
355 llvm::errs() <<
"Error while converting the relative path specified by " 356 "--compile-commands-dir to an absolute path: " 357 << EC.message() <<
". The argument will be ignored.\n";
359 CompileCommandsDirPath = Path.str();
363 <<
"Path specified by --compile-commands-dir does not exist. The " 364 "argument will be ignored.\n";
383 std::unique_ptr<SymbolIndex> StaticIdx;
384 std::future<void> AsyncIndexLoad;
388 StaticIdx.
reset(Placeholder =
new SwapIndex(llvm::make_unique<MemIndex>()));
389 AsyncIndexLoad = runAsync<void>([Placeholder] {
391 Placeholder->
reset(std::move(Idx));
394 AsyncIndexLoad.wait();
414 llvm::sys::ChangeStdinToBinary();
416 std::unique_ptr<Transport> TransportLayer;
417 if (getenv(
"CLANGD_AS_XPC_SERVICE")) {
421 llvm::errs() <<
"This clangd binary wasn't built with XPC support.\n";
427 InputMirrorStream ? InputMirrorStream.getPointer() :
nullptr,
432 *TransportLayer, CCOpts, CompileCommandsDirPath,
434 llvm::set_thread_name(
"clangd.main");
435 return LSPServer.run() ? 0
bool ShowOrigins
Expose origins of completion items in the label (for debugging).
bool BundleOverloads
Combine overloads into a single completion item where possible.
size_t Limit
Limit the number of results returned (0 means no limit).
int main(int argc, char *argv[])
std::unique_ptr< SymbolIndex > loadIndex(llvm::StringRef SymbolFilename, bool UseDex)
bool BackgroundIndex
If true, ClangdServer automatically indexes files in the current project on background threads...
static llvm::cl::opt< int > BackgroundIndexRebuildPeriod("background-index-rebuild-period", llvm::cl::desc("If set to non-zero, the background index rebuilds the symbol index " "periodically every X milliseconds; otherwise, the " "symbol index will be updated for each indexed file."), llvm::cl::init(5000), llvm::cl::Hidden)
void preventThreadStarvationInTests()
static llvm::cl::opt< JSONStreamStyle > InputStyle("input-style", llvm::cl::desc("Input JSON stream encoding"), llvm::cl::values(clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"), clEnumValN(JSONStreamStyle::Delimited, "delimited", "messages delimited by --- lines, with # comment support")), llvm::cl::init(JSONStreamStyle::Standard))
static llvm::cl::opt< int > LimitResults("limit-results", llvm::cl::desc("Limit the number of results returned by clangd. " "0 means no limit."), llvm::cl::init(100))
URIScheme is an extension point for teaching clangd to recognize a custom URI scheme.
std::unique_ptr< Transport > newXPCTransport()
static llvm::cl::opt< CompletionStyleFlag > CompletionStyle("completion-style", llvm::cl::desc("Granularity of code completion suggestions"), llvm::cl::values(clEnumValN(Detailed, "detailed", "One completion item for each semantically distinct " "completion, with full type information."), clEnumValN(Bundled, "bundled", "Similar completion items (e.g. function overloads) are " "combined. Type information shown where possible.")), llvm::cl::init(Detailed))
def make_absolute(f, directory)
unsigned AsyncThreadsCount
To process requests asynchronously, ClangdServer spawns worker threads.
bool BuildDynamicSymbolIndex
If true, ClangdServer builds a dynamic in-memory index for symbols in opened files and uses the index...
static llvm::cl::opt< bool > AllScopesCompletion("all-scopes-completion", llvm::cl::desc("If set to true, code completion will include index symbols that are " "not defined in the scopes (e.g. " "namespaces) visible from the code completion point. Such completions " "can insert scope qualifiers."), llvm::cl::init(true))
static llvm::cl::opt< Logger::Level > LogLevel("log", llvm::cl::desc("Verbosity of log messages written to stderr"), llvm::cl::values(clEnumValN(Logger::Error, "error", "Error messages only"), clEnumValN(Logger::Info, "info", "High level execution tracing"), clEnumValN(Logger::Debug, "verbose", "Low level details")), llvm::cl::init(Logger::Info))
static llvm::cl::opt< bool > PrettyPrint("pretty", llvm::cl::desc("Pretty-print JSON output"), llvm::cl::init(false))
static ClangTidyModuleRegistry::Add< AbseilModule > X("abseil-module", "Add Abseil checks.")
static llvm::cl::opt< bool > UseDex("use-dex-index", llvm::cl::desc("Use experimental Dex dynamic index."), llvm::cl::init(false), llvm::cl::Hidden)
static llvm::cl::opt< Path > InputMirrorFile("input-mirror-file", llvm::cl::desc("Mirror all LSP input to the specified file. Useful for debugging."), llvm::cl::init(""), llvm::cl::Hidden)
static llvm::cl::opt< unsigned > WorkerThreadsCount("j", llvm::cl::desc("Number of async workers used by clangd"), llvm::cl::init(getDefaultAsyncThreadsCount()))
Interface to allow custom logging in clangd.
bool SpeculativeIndexRequest
If set to true, this will send an asynchronous speculative index request, based on the index request ...
static llvm::cl::opt< bool > ShowOrigins("debug-origin", llvm::cl::desc("Show origins of completion items"), llvm::cl::init(CodeCompleteOptions().ShowOrigins), llvm::cl::Hidden)
static llvm::cl::opt< bool > EnableTestScheme("enable-test-uri-scheme", llvm::cl::desc("Enable 'test:' URI scheme. Only use in lit tests."), llvm::cl::init(false), llvm::cl::Hidden)
std::string Path
A typedef to represent a file path.
Only one LoggingSession can be active at a time.
bool IncludeIneligibleResults
Include results that are not legal completions in the current context.
std::unique_ptr< Transport > newJSONTransport(std::FILE *In, llvm::raw_ostream &Out, llvm::raw_ostream *InMirror, bool Pretty, JSONStreamStyle Style)
static llvm::cl::opt< bool > RunSynchronously("run-synchronously", llvm::cl::desc("Parse on main thread. If set, -j is ignored"), llvm::cl::init(false), llvm::cl::Hidden)
size_t BackgroundIndexRebuildPeriodMs
If set to non-zero, the background index rebuilds the symbol index periodically every BuildIndexPerio...
static llvm::cl::opt< Path > ResourceDir("resource-dir", llvm::cl::desc("Directory for system clang headers"), llvm::cl::init(""), llvm::cl::Hidden)
bool HeavyweightDynamicSymbolIndex
Use a heavier and faster in-memory index implementation.
unsigned getDefaultAsyncThreadsCount()
Returns a number of a default async threads to use for TUScheduler.
static llvm::cl::opt< PCHStorageFlag > PCHStorage("pch-storage", llvm::cl::desc("Storing PCHs in memory increases memory usages, but may " "improve performance"), llvm::cl::values(clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"), clEnumValN(PCHStorageFlag::Memory, "memory", "store PCHs in memory")), llvm::cl::init(PCHStorageFlag::Disk))
static llvm::cl::opt< bool > IncludeIneligibleResults("include-ineligible-results", llvm::cl::desc("Include ineligible completion results (e.g. private members)"), llvm::cl::init(CodeCompleteOptions().IncludeIneligibleResults), llvm::cl::Hidden)
bool StorePreamblesInMemory
Cached preambles are potentially large. If false, store them on disk.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::Optional< std::string > ResourceDir
The resource directory is used to find internal headers, overriding defaults and -resource-dir compil...
std::unique_ptr< EventTracer > createJSONTracer(llvm::raw_ostream &OS, bool Pretty)
Create an instance of EventTracer that produces an output in the Trace Event format supported by Chro...
static llvm::cl::opt< bool > Test("lit-test", llvm::cl::desc("Abbreviation for -input-style=delimited -pretty " "-run-synchronously -enable-test-scheme. " "Intended to simplify lit tests."), llvm::cl::init(false), llvm::cl::Hidden)
struct clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator IncludeIndicator
A URI describes the location of a source file.
static llvm::cl::opt< bool > HeaderInsertionDecorators("header-insertion-decorators", llvm::cl::desc("Prepend a circular dot or space before the completion " "label, depending on whether " "an include line will be inserted or not."), llvm::cl::init(true))
static llvm::cl::opt< bool > EnableFunctionArgSnippets("function-arg-placeholders", llvm::cl::desc("When disabled, completions contain only parentheses for " "function calls. When enabled, completions also contain " "placeholders for method parameters."), llvm::cl::init(CodeCompleteOptions().EnableFunctionArgSnippets))
bool EnableFunctionArgSnippets
Whether to generate snippets for function arguments on code-completion.
static llvm::cl::opt< bool > EnableIndex("index", llvm::cl::desc("Enable index-based features. By default, clangd maintains an index " "built from symbols in opened files. Global index support needs to " "enabled separatedly."), llvm::cl::init(true), llvm::cl::Hidden)
static llvm::cl::opt< Path > IndexFile("index-file", llvm::cl::desc("Index file to build the static index. The file must have been created " "by a compatible clangd-index.\ "WARNING:This option is experimental only, and will be removed " "eventually. Don 't rely on it."), llvm::cl::init(""), llvm::cl::Hidden)
static llvm::cl::opt< bool > EnableBackgroundIndex("background-index", llvm::cl::desc("Index project code in the background and persist index on disk. " "Experimental"), llvm::cl::init(false), llvm::cl::Hidden)
bool AllScopes
Whether to include index symbols that are not defined in the scopes visible from the code completion ...
This class exposes ClangdServer's capabilities via Language Server Protocol.
static llvm::cl::opt< Path > CompileCommandsDir("compile-commands-dir", llvm::cl::desc("Specify a path to look for compile_commands.json. If path " "is invalid, clangd will look in the current directory and " "parent paths of each source file."))
SymbolIndex * StaticIndex
If set, use this index to augment code completion results.
void reset(std::unique_ptr< SymbolIndex >)