15 #include "clang/Basic/Version.h" 16 #include "llvm/Support/CommandLine.h" 17 #include "llvm/Support/FileSystem.h" 18 #include "llvm/Support/Path.h" 19 #include "llvm/Support/Program.h" 20 #include "llvm/Support/Signals.h" 21 #include "llvm/Support/raw_ostream.h" 28 using namespace clang;
37 std::unique_ptr<SymbolIndex> buildStaticIndex(llvm::StringRef
YamlSymbolFile) {
38 auto Buffer = llvm::MemoryBuffer::getFile(YamlSymbolFile);
40 llvm::errs() <<
"Can't open " << YamlSymbolFile <<
"\n";
53 "compile-commands-dir",
54 llvm::cl::desc(
"Specify a path to look for compile_commands.json. If path " 55 "is invalid, clangd will look in the current directory and " 56 "parent paths of each source file."));
58 static llvm::cl::opt<unsigned>
60 llvm::cl::desc(
"Number of async workers used by clangd"),
70 llvm::cl::desc(
"Granularity of code completion suggestions"),
73 "One completion item for each semantically distinct " 74 "completion, with full type information."),
76 "Similar completion items (e.g. function overloads) are " 77 "combined. Type information shown where possible.")),
83 "include-ineligible-results",
85 "Include ineligible completion results (e.g. private members)"),
89 static llvm::cl::opt<JSONStreamStyle>
InputStyle(
90 "input-style", llvm::cl::desc(
"Input JSON stream encoding"),
94 "messages delimited by --- lines, with # comment support")),
97 static llvm::cl::opt<bool>
98 PrettyPrint(
"pretty", llvm::cl::desc(
"Pretty-print JSON output"),
99 llvm::cl::init(
false));
101 static llvm::cl::opt<Logger::Level>
LogLevel(
102 "log", llvm::cl::desc(
"Verbosity of log messages written to stderr"),
103 llvm::cl::values(clEnumValN(
Logger::Error,
"error",
"Error messages only"),
105 "High level execution tracing"),
109 static llvm::cl::opt<bool>
Test(
112 "Abbreviation for -input-style=delimited -pretty -run-synchronously. " 113 "Intended to simplify lit tests."),
114 llvm::cl::init(
false), llvm::cl::Hidden);
116 static llvm::cl::opt<PCHStorageFlag>
PCHStorage(
118 llvm::cl::desc(
"Storing PCHs in memory increases memory usages, but may " 119 "improve performance"),
121 clEnumValN(PCHStorageFlag::Disk,
"disk",
"store PCHs on disk"),
122 clEnumValN(PCHStorageFlag::Memory,
"memory",
"store PCHs in memory")),
123 llvm::cl::init(PCHStorageFlag::Disk));
127 llvm::cl::desc(
"Limit the number of results returned by clangd. " 128 "0 means no limit."),
129 llvm::cl::init(100));
133 llvm::cl::desc(
"Parse on main thread. If set, -j is ignored"),
134 llvm::cl::init(
false), llvm::cl::Hidden);
136 static llvm::cl::opt<Path>
138 llvm::cl::desc(
"Directory for system clang headers"),
139 llvm::cl::init(
""), llvm::cl::Hidden);
144 "Mirror all LSP input to the specified file. Useful for debugging."),
145 llvm::cl::init(
""), llvm::cl::Hidden);
149 llvm::cl::desc(
"Enable index-based features such as global code completion " 150 "and searching for symbols." 151 "Clang uses an index built from symbols in opened files"),
152 llvm::cl::init(
true));
154 static llvm::cl::opt<bool>
156 llvm::cl::desc(
"Show origins of completion items"),
161 "header-insertion-decorators",
162 llvm::cl::desc(
"Prepend a circular dot or space before the completion " 163 "label, depending on wether " 164 "an include line will be inserted or not."),
165 llvm::cl::init(
true));
170 "YAML-format global symbol file to build the static index. Clangd will " 171 "use the static index for global code completion.\n" 172 "WARNING: This option is experimental only, and will be removed " 173 "eventually. Don't rely on it."),
174 llvm::cl::init(
""), llvm::cl::Hidden);
176 int main(
int argc,
char *argv[]) {
177 llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
178 llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
179 OS << clang::getClangToolFullVersion(
"clangd") <<
"\n";
181 llvm::cl::ParseCommandLineOptions(
183 "clangd is a language server that provides IDE-like features to editors. " 184 "\n\nIt should be used via an editor plugin rather than invoked directly." 185 "For more information, see:" 186 "\n\thttps://clang.llvm.org/extra/clangd.html" 187 "\n\thttps://microsoft.github.io/language-server-protocol/");
195 llvm::errs() <<
"A number of worker threads cannot be 0. Did you mean to " 196 "specify -run-synchronously?";
202 llvm::errs() <<
"Ignoring -j because -run-synchronously is set.\n";
207 llvm::Optional<llvm::raw_fd_ostream> InputMirrorStream;
211 llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
213 InputMirrorStream.reset();
214 llvm::errs() <<
"Error while opening an input mirror file: " 222 llvm::Optional<llvm::raw_fd_ostream> TraceStream;
223 std::unique_ptr<trace::EventTracer> Tracer;
224 if (
auto *TraceFile = getenv(
"CLANGD_TRACE")) {
226 TraceStream.emplace(TraceFile, EC,
227 llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write);
230 llvm::errs() <<
"Error while opening trace file " << TraceFile <<
": " 237 llvm::Optional<trace::Session> TracingSession;
239 TracingSession.emplace(*Tracer);
242 InputMirrorStream ? InputMirrorStream.getPointer() :
nullptr,
249 llvm::Optional<Path> CompileCommandsDirPath;
254 llvm::errs() <<
"Path specified by --compile-commands-dir either does not " 255 "exist or is not an absolute " 256 "path. The argument will be ignored.\n";
264 case PCHStorageFlag::Memory:
267 case PCHStorageFlag::Disk:
274 std::unique_ptr<SymbolIndex> StaticIdx;
293 constexpr
int NoShutdownRequestErrorCode = 1;
294 llvm::set_thread_name(
"clangd.main");
296 llvm::sys::ChangeStdinToBinary();
297 return LSPServer.
run(stdin,
InputStyle) ? 0 : NoShutdownRequestErrorCode;
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).
Encapsulates output and logs streams and provides thread-safe access to them.
void build(std::shared_ptr< std::vector< const Symbol *>> Symbols)
(Re-)Build index for Symbols.
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))
int main(int argc, char *argv[])
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))
void insert(const Symbol &S)
bool run(std::FILE *In, JSONStreamStyle InputStyle=JSONStreamStyle::Standard)
Run LSP server loop, receiving input for it from In.
Documents should not be synced at all.
unsigned AsyncThreadsCount
To process requests asynchronously, ClangdServer spawns worker threads.
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))
bool BuildDynamicSymbolIndex
If true, ClangdServer builds a dynamic in-memory index for symbols in opened files and uses the index...
static llvm::cl::opt< unsigned > WorkerThreadsCount("j", llvm::cl::desc("Number of async workers used by clangd"), llvm::cl::init(getDefaultAsyncThreadsCount()))
static llvm::cl::opt< Path > ResourceDir("resource-dir", llvm::cl::desc("Directory for system clang headers"), llvm::cl::init(""), llvm::cl::Hidden)
static llvm::cl::opt< Path > YamlSymbolFile("yaml-symbol-file", llvm::cl::desc("YAML-format global symbol file to build the static index. Clangd will " "use the static index for global code completion.\ "WARNING:This option is experimental only, and will be removed " "eventually. Don 't rely on it."), llvm::cl::init(""), llvm::cl::Hidden)
Only one LoggingSession can be active at a time.
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."))
bool IncludeIneligibleResults
Include results that are not legal completions in the current context.
static llvm::cl::opt< bool > Test("lit-test", llvm::cl::desc("Abbreviation for -input-style=delimited -pretty -run-synchronously. " "Intended to simplify lit tests."), llvm::cl::init(false), llvm::cl::Hidden)
Messages are delimited by a '—' line. Comment lines start with #.
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))
unsigned getDefaultAsyncThreadsCount()
Returns a number of a default async threads to use for TUScheduler.
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)
bool StorePreamblesInMemory
Cached preambles are potentially large. If false, store them on disk.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static llvm::cl::opt< bool > IncludeIneligibleResults("include-ineligible-results", llvm::cl::desc("Include ineligible completion results (e.g. private members)"), llvm::cl::init(clangd::CodeCompleteOptions().IncludeIneligibleResults), llvm::cl::Hidden)
static llvm::cl::opt< bool > HeaderInsertionDecorators("header-insertion-decorators", llvm::cl::desc("Prepend a circular dot or space before the completion " "label, depending on wether " "an include line will be inserted or not."), llvm::cl::init(true))
static llvm::cl::opt< bool > EnableIndex("index", llvm::cl::desc("Enable index-based features such as global code completion " "and searching for symbols." "Clang uses an index built from symbols in opened files"), llvm::cl::init(true))
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...
struct clang::clangd::CodeCompleteOptions::IncludeInsertionIndicator IncludeIndicator
Encoding per the LSP specification, with mandatory Content-Length header.
static llvm::cl::opt< bool > PrettyPrint("pretty", llvm::cl::desc("Pretty-print JSON output"), llvm::cl::init(false))
SymbolSlab symbolsFromYAML(llvm::StringRef YAMLContent)
static llvm::cl::opt< bool > ShowOrigins("debug-origin", llvm::cl::desc("Show origins of completion items"), llvm::cl::init(clangd::CodeCompleteOptions().ShowOrigins), llvm::cl::Hidden)
llvm::Optional< StringRef > ResourceDir
The resource directory is used to find internal headers, overriding defaults and -resource-dir compil...
This class provides implementation of an LSP server, glueing the JSON dispatch and ClangdServer toget...
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)
SymbolIndex * StaticIndex
If set, use this index to augment code completion results.
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))