Index: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp =================================================================== --- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp @@ -35,6 +35,7 @@ namespace clang { namespace clangd { +namespace { using llvm::cl::cat; using llvm::cl::CommaSeparated; @@ -43,151 +44,153 @@ using llvm::cl::init; using llvm::cl::list; using llvm::cl::opt; +using llvm::cl::OptionCategory; using llvm::cl::values; -static opt CompileCommandsDir{ +// All flags must be placed in a category, or they will be shown neither in +// --help, nor --help-hidden! +OptionCategory CompileCommands("clangd compilation flags options"); +OptionCategory Features("clangd feature options"); +OptionCategory Misc("clangd miscellaneous options"); +OptionCategory Protocol("clangd protocol and logging options"); +const OptionCategory *ClangdCategories[] = {&Features, &Protocol, + &CompileCommands, &Misc}; + +enum CompileArgsFrom { LSPCompileArgs, FilesystemCompileArgs }; +opt CompileArgsFrom{ + "compile_args_from", + cat(CompileCommands), + desc("The source of compile commands"), + values(clEnumValN(LSPCompileArgs, "lsp", + "All compile commands come from LSP and " + "'compile_commands.json' files are ignored"), + clEnumValN(FilesystemCompileArgs, "filesystem", + "All compile commands come from the " + "'compile_commands.json' files")), + init(FilesystemCompileArgs), + Hidden, +}; + +opt CompileCommandsDir{ "compile-commands-dir", + cat(CompileCommands), 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"), }; -static opt WorkerThreadsCount{ - "j", - desc("Number of async workers used by clangd"), - init(getDefaultAsyncThreadsCount()), +opt ResourceDir{ + "resource-dir", + cat(CompileCommands), + desc("Directory for system clang headers"), + init(""), + Hidden, }; -// FIXME: also support "plain" style where signatures are always omitted. -enum CompletionStyleFlag { Detailed, Bundled }; -static opt CompletionStyle{ - "completion-style", - desc("Granularity of code completion suggestions"), - 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")), +list QueryDriverGlobs{ + "query-driver", + cat(CompileCommands), + desc( + "Comma separated list of globs for white-listing gcc-compatible " + "drivers that are safe to execute. Drivers matching any of these globs " + "will be used to extract system includes. e.g. " + "/usr/bin/**/clang-*,/path/to/repo/**/g++-*"), + CommaSeparated, }; // FIXME: Flags are the wrong mechanism for user preferences. // We should probably read a dotfile or similar. -static opt IncludeIneligibleResults{ - "include-ineligible-results", - desc("Include ineligible completion results (e.g. private members)"), - init(CodeCompleteOptions().IncludeIneligibleResults), - Hidden, -}; - -static opt InputStyle{ - "input-style", - desc("Input JSON stream encoding"), - values( - clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"), - clEnumValN(JSONStreamStyle::Delimited, "delimited", - "messages delimited by --- lines, with # comment support")), - init(JSONStreamStyle::Standard), - Hidden, -}; - -static opt PrettyPrint{ - "pretty", - desc("Pretty-print JSON output"), - init(false), -}; - -static opt LogLevel{ - "log", - desc("Verbosity of log messages written to stderr"), - values(clEnumValN(Logger::Error, "error", "Error messages only"), - clEnumValN(Logger::Info, "info", "High level execution tracing"), - clEnumValN(Logger::Debug, "verbose", "Low level details")), - init(Logger::Info), -}; - -static opt Test{ - "lit-test", - desc("Abbreviation for -input-style=delimited -pretty -sync " - "-enable-test-scheme -log=verbose." - "Intended to simplify lit tests"), - init(false), - Hidden, +opt AllScopesCompletion{ + "all-scopes-completion", + cat(Features), + 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"), + init(true), }; -static opt EnableTestScheme{ - "enable-test-uri-scheme", - desc("Enable 'test:' URI scheme. Only use in lit tests"), - init(false), +opt ShowOrigins{ + "debug-origin", + cat(Features), + desc("Show origins of completion items"), + init(CodeCompleteOptions().ShowOrigins), Hidden, }; -enum PCHStorageFlag { Disk, Memory }; -static opt PCHStorage{ - "pch-storage", - desc("Storing PCHs in memory increases memory usages, but may " - "improve performance"), - values( - clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"), - clEnumValN(PCHStorageFlag::Memory, "memory", "store PCHs in memory")), - init(PCHStorageFlag::Disk), -}; - -static opt LimitResults{ - "limit-results", - desc("Limit the number of results returned by clangd. " - "0 means no limit (default=100)"), - init(100), +opt EnableBackgroundIndex{ + "background-index", + cat(Features), + desc("Index project code in the background and persist index on disk. " + "Experimental"), + init(true), }; -static opt Sync{ - "sync", - desc("Parse on main thread. If set, -j is ignored"), - init(false), - Hidden, +opt EnableClangTidy{ + "clang-tidy", + cat(Features), + desc("Enable clang-tidy diagnostics"), + init(true), }; -static opt ResourceDir{ - "resource-dir", - desc("Directory for system clang headers"), +opt ClangTidyChecks{ + "clang-tidy-checks", + cat(Features), + desc("List of clang-tidy checks to run (this will override " + ".clang-tidy files). Only meaningful when -clang-tidy flag is on"), init(""), - Hidden, }; -static opt InputMirrorFile{ - "input-mirror-file", - desc("Mirror all LSP input to the specified file. Useful for debugging"), - init(""), +opt CodeCompletionParse{ + "completion-parse", + cat(Features), + desc("Whether the clang-parser is used for code-completion"), + values(clEnumValN(CodeCompleteOptions::AlwaysParse, "always", + "Block until the parser can be used"), + clEnumValN(CodeCompleteOptions::ParseIfReady, "auto", + "Use text-based completion if the parser " + "is not ready"), + clEnumValN(CodeCompleteOptions::NeverParse, "never", + "Always used text-based completion")), + init(CodeCompleteOptions().RunParser), Hidden, }; -static opt EnableIndex{ - "index", - desc("Enable index-based features. By default, clangd maintains an index " - "built from symbols in opened files. Global index support needs to " - "enabled separatedly"), - init(true), - Hidden, +// FIXME: also support "plain" style where signatures are always omitted. +enum CompletionStyleFlag { Detailed, Bundled }; +opt CompletionStyle{ + "completion-style", + cat(Features), + desc("Granularity of code completion suggestions"), + 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")), }; -static opt AllScopesCompletion{ - "all-scopes-completion", - 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"), - init(true), +opt FallbackStyle{ + "fallback-style", + cat(Features), + desc("clang-format style to apply by default when " + "no .clang-format file is found"), + init(clang::format::DefaultFallbackStyle), }; -static opt ShowOrigins{ - "debug-origin", - desc("Show origins of completion items"), - init(CodeCompleteOptions().ShowOrigins), +opt EnableFunctionArgSnippets{ + "function-arg-placeholders", + cat(Features), + desc("When disabled, completions contain only parentheses for " + "function calls. When enabled, completions also contain " + "placeholders for method parameters"), + init(CodeCompleteOptions().EnableFunctionArgSnippets), Hidden, }; -static opt HeaderInsertion{ +opt HeaderInsertion{ "header-insertion", + cat(Features), desc("Add #include directives when accepting code completions"), init(CodeCompleteOptions().InsertIncludes), values( @@ -201,16 +204,75 @@ "Never insert #include directives as part of code completion")), }; -static opt HeaderInsertionDecorators{ +opt HeaderInsertionDecorators{ "header-insertion-decorators", + cat(Features), desc("Prepend a circular dot or space before the completion " "label, depending on whether " "an include line will be inserted or not"), init(true), }; -static opt IndexFile{ +opt HiddenFeatures{ + "hidden-features", + cat(Features), + desc("Enable hidden features mostly useful to clangd developers"), + init(false), + Hidden, +}; + +opt IncludeIneligibleResults{ + "include-ineligible-results", + cat(Features), + desc("Include ineligible completion results (e.g. private members)"), + init(CodeCompleteOptions().IncludeIneligibleResults), + Hidden, +}; + +opt EnableIndex{ + "index", + cat(Features), + desc("Enable index-based features. By default, clangd maintains an index " + "built from symbols in opened files. Global index support needs to " + "enabled separatedly"), + init(true), + Hidden, +}; + +opt LimitResults{ + "limit-results", + cat(Features), + desc("Limit the number of results returned by clangd. " + "0 means no limit (default=100)"), + init(100), +}; + +opt SuggestMissingIncludes{ + "suggest-missing-includes", + cat(Features), + desc("Attempts to fix diagnostic errors caused by missing " + "includes using index"), + init(true), +}; + +list TweakList{ + "tweaks", + cat(Features), + desc("Specify a list of Tweaks to enable (only for clangd developers)."), + Hidden, + CommaSeparated, +}; + +opt WorkerThreadsCount{ + "j", + cat(Misc), + desc("Number of async workers used by clangd"), + init(getDefaultAsyncThreadsCount()), +}; + +opt IndexFile{ "index-file", + cat(Misc), desc( "Index file to build the static index. The file must have been created " "by a compatible clangd-indexer\n" @@ -220,65 +282,77 @@ Hidden, }; -static opt EnableBackgroundIndex{ - "background-index", - desc("Index project code in the background and persist index on disk. " - "Experimental"), - init(true), +opt Test{ + "lit-test", + cat(Misc), + desc("Abbreviation for -input-style=delimited -pretty -sync " + "-enable-test-scheme -log=verbose. " + "Intended to simplify lit tests"), + init(false), + Hidden, }; -enum CompileArgsFrom { LSPCompileArgs, FilesystemCompileArgs }; -static opt CompileArgsFrom{ - "compile_args_from", - desc("The source of compile commands"), - values(clEnumValN(LSPCompileArgs, "lsp", - "All compile commands come from LSP and " - "'compile_commands.json' files are ignored"), - clEnumValN(FilesystemCompileArgs, "filesystem", - "All compile commands come from the " - "'compile_commands.json' files")), - init(FilesystemCompileArgs), - Hidden, +enum PCHStorageFlag { Disk, Memory }; +opt PCHStorage{ + "pch-storage", + cat(Misc), + desc("Storing PCHs in memory increases memory usages, but may " + "improve performance"), + values( + clEnumValN(PCHStorageFlag::Disk, "disk", "store PCHs on disk"), + clEnumValN(PCHStorageFlag::Memory, "memory", "store PCHs in memory")), + init(PCHStorageFlag::Disk), }; -static opt EnableFunctionArgSnippets{ - "function-arg-placeholders", - desc("When disabled, completions contain only parentheses for " - "function calls. When enabled, completions also contain " - "placeholders for method parameters"), - init(CodeCompleteOptions().EnableFunctionArgSnippets), +opt Sync{ + "sync", + cat(Misc), + desc("Parse on main thread. If set, -j is ignored"), + init(false), Hidden, }; -static opt ClangTidyChecks{ - "clang-tidy-checks", - desc("List of clang-tidy checks to run (this will override " - ".clang-tidy files). Only meaningful when -clang-tidy flag is on"), - init(""), +opt InputStyle{ + "input-style", + cat(Protocol), + desc("Input JSON stream encoding"), + values( + clEnumValN(JSONStreamStyle::Standard, "standard", "usual LSP protocol"), + clEnumValN(JSONStreamStyle::Delimited, "delimited", + "messages delimited by --- lines, with # comment support")), + init(JSONStreamStyle::Standard), + Hidden, }; -static opt EnableClangTidy{ - "clang-tidy", - desc("Enable clang-tidy diagnostics"), - init(true), +opt EnableTestScheme{ + "enable-test-uri-scheme", + cat(Protocol), + desc("Enable 'test:' URI scheme. Only use in lit tests"), + init(false), + Hidden, }; -static opt FallbackStyle{ - "fallback-style", - desc("clang-format style to apply by default when " - "no .clang-format file is found"), - init(clang::format::DefaultFallbackStyle), +opt InputMirrorFile{ + "input-mirror-file", + cat(Protocol), + desc("Mirror all LSP input to the specified file. Useful for debugging"), + init(""), + Hidden, }; -static opt SuggestMissingIncludes{ - "suggest-missing-includes", - desc("Attempts to fix diagnostic errors caused by missing " - "includes using index"), - init(true), +opt LogLevel{ + "log", + cat(Protocol), + desc("Verbosity of log messages written to stderr"), + values(clEnumValN(Logger::Error, "error", "Error messages only"), + clEnumValN(Logger::Info, "info", "High level execution tracing"), + clEnumValN(Logger::Debug, "verbose", "Low level details")), + init(Logger::Info), }; -static opt ForceOffsetEncoding{ +opt ForceOffsetEncoding{ "offset-encoding", + cat(Protocol), desc("Force the offsetEncoding used for character positions. " "This bypasses negotiation via client capabilities"), values( @@ -288,46 +362,13 @@ init(OffsetEncoding::UnsupportedEncoding), }; -static opt CodeCompletionParse{ - "completion-parse", - desc("Whether the clang-parser is used for code-completion"), - values(clEnumValN(CodeCompleteOptions::AlwaysParse, "always", - "Block until the parser can be used"), - clEnumValN(CodeCompleteOptions::ParseIfReady, "auto", - "Use text-based completion if the parser " - "is not ready"), - clEnumValN(CodeCompleteOptions::NeverParse, "never", - "Always used text-based completion")), - init(CodeCompleteOptions().RunParser), - Hidden, -}; - -static opt HiddenFeatures{ - "hidden-features", - desc("Enable hidden features mostly useful to clangd developers"), +opt PrettyPrint{ + "pretty", + cat(Protocol), + desc("Pretty-print JSON output"), init(false), - Hidden, }; -static list QueryDriverGlobs{ - "query-driver", - desc( - "Comma separated list of globs for white-listing gcc-compatible " - "drivers that are safe to execute. Drivers matching any of these globs " - "will be used to extract system includes. e.g. " - "/usr/bin/**/clang-*,/path/to/repo/**/g++-*"), - CommaSeparated, -}; - -static list TweakList{ - "tweaks", - desc("Specify a list of Tweaks to enable (only for clangd developers)."), - Hidden, - CommaSeparated, -}; - -namespace { - /// \brief Supports a test URI scheme with relaxed constraints for lit tests. /// The path in a test URI will be combined with a platform-specific fake /// directory to form an absolute path. For example, test:///a.cpp is resolved @@ -392,6 +433,7 @@ llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) { OS << clang::getClangToolFullVersion("clangd") << "\n"; }); + llvm::cl::HideUnrelatedOptions(ClangdCategories); llvm::cl::ParseCommandLineOptions( argc, argv, "clangd is a language server that provides IDE-like features to editors. "