[llvm-branch-commits] [clang-tools-extra-branch] r367025 - Merging r366811, r366880, r366900, r366991 and r366992:

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jul 25 08:06:35 PDT 2019


Author: hans
Date: Thu Jul 25 08:06:35 2019
New Revision: 367025

URL: http://llvm.org/viewvc/llvm-project?rev=367025&view=rev
Log:
Merging r366811, r366880, r366900, r366991 and r366992:

------------------------------------------------------------------------
r366811 | sammccall | 2019-07-23 16:30:28 +0200 (Tue, 23 Jul 2019) | 9 lines

[clangd] Log version, cwd, args, and transport on startup. NFC

Reviewers: hokein

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65146
------------------------------------------------------------------------

------------------------------------------------------------------------
r366880 | sammccall | 2019-07-24 11:33:27 +0200 (Wed, 24 Jul 2019) | 9 lines

[clangd] Reformat use of cl::opt: use unqualified name and don't bin-pack attributes. NFC

Reviewers: kadircet

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65154
------------------------------------------------------------------------

------------------------------------------------------------------------
r366900 | sammccall | 2019-07-24 14:41:52 +0200 (Wed, 24 Jul 2019) | 16 lines

[clangd] Add categories to help options, and only show clangd options.

Summary:
Restricting the categories prevents extra unwanted options from creeping into
help (D60663), and removes a bunch of noise from --help-hidden.

While here, remove `static` from the opts in favor of an anon namespace, to
reduce the noise level.

Reviewers: hokein

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65200
------------------------------------------------------------------------

------------------------------------------------------------------------
r366991 | sammccall | 2019-07-25 09:54:48 +0200 (Thu, 25 Jul 2019) | 13 lines

[clangd] Also accept flags from CLANGD_FLAGS variable.

This simplifies various workflows, particularly in debugging/development.
e.g. editors will tend to propagate flags, so you can run
`env CLANGD_FLAGS=-input-mirror-file=/tmp/mirror vim foo.cc` rather than
change the configuration in a persistent way.
(This also gives us a generic lever when we don't know how to customize
the flags in some particular LSP client).

While here, add a test for this and other startup logging, and fix a
couple of direct writes to errs() that should have been logs.

Differential Revision: https://reviews.llvm.org/D65153
------------------------------------------------------------------------

------------------------------------------------------------------------
r366992 | sammccall | 2019-07-25 10:00:54 +0200 (Thu, 25 Jul 2019) | 9 lines

[clangd] Provide help text to users who run `clangd` in a terminal.

Reviewers: hokein

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65201
------------------------------------------------------------------------

Added:
    clang-tools-extra/branches/release_90/clangd/test/log.test
      - copied unchanged from r366991, clang-tools-extra/trunk/clangd/test/log.test
Modified:
    clang-tools-extra/branches/release_90/   (props changed)
    clang-tools-extra/branches/release_90/clangd/index/Serialization.cpp
    clang-tools-extra/branches/release_90/clangd/tool/ClangdMain.cpp

Propchange: clang-tools-extra/branches/release_90/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Jul 25 08:06:35 2019
@@ -1 +1 @@
-/clang-tools-extra/trunk:366443,366451,366455,366559,366687
+/clang-tools-extra/trunk:366443,366451,366455,366559,366687,366811,366880,366900,366991-366992

Modified: clang-tools-extra/branches/release_90/clangd/index/Serialization.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/branches/release_90/clangd/index/Serialization.cpp?rev=367025&r1=367024&r2=367025&view=diff
==============================================================================
--- clang-tools-extra/branches/release_90/clangd/index/Serialization.cpp (original)
+++ clang-tools-extra/branches/release_90/clangd/index/Serialization.cpp Thu Jul 25 08:06:35 2019
@@ -690,7 +690,7 @@ std::unique_ptr<SymbolIndex> loadIndex(l
   trace::Span OverallTracer("LoadIndex");
   auto Buffer = llvm::MemoryBuffer::getFile(SymbolFilename);
   if (!Buffer) {
-    llvm::errs() << "Can't open " << SymbolFilename << "\n";
+    elog("Can't open {0}", SymbolFilename);
     return nullptr;
   }
 
@@ -707,7 +707,7 @@ std::unique_ptr<SymbolIndex> loadIndex(l
       if (I->Relations)
         Relations = std::move(*I->Relations);
     } else {
-      llvm::errs() << "Bad Index: " << llvm::toString(I.takeError()) << "\n";
+      elog("Bad Index: {0}", I.takeError());
       return nullptr;
     }
   }

Modified: clang-tools-extra/branches/release_90/clangd/tool/ClangdMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/branches/release_90/clangd/tool/ClangdMain.cpp?rev=367025&r1=367024&r2=367025&view=diff
==============================================================================
--- clang-tools-extra/branches/release_90/clangd/tool/ClangdMain.cpp (original)
+++ clang-tools-extra/branches/release_90/clangd/tool/ClangdMain.cpp Thu Jul 25 08:06:35 2019
@@ -22,6 +22,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/TargetSelect.h"
@@ -35,129 +36,165 @@
 
 namespace clang {
 namespace clangd {
+namespace {
+
+using llvm::cl::cat;
+using llvm::cl::CommaSeparated;
+using llvm::cl::desc;
+using llvm::cl::Hidden;
+using llvm::cl::init;
+using llvm::cl::list;
+using llvm::cl::opt;
+using llvm::cl::OptionCategory;
+using llvm::cl::values;
+
+// 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};
 
-static llvm::cl::opt<Path> CompileCommandsDir(
+enum CompileArgsFrom { LSPCompileArgs, FilesystemCompileArgs };
+opt<CompileArgsFrom> 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<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"));
-
-static llvm::cl::opt<unsigned>
-    WorkerThreadsCount("j",
-                       llvm::cl::desc("Number of async workers used by clangd"),
-                       llvm::cl::init(getDefaultAsyncThreadsCount()));
+    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"),
+};
 
-// FIXME: also support "plain" style where signatures are always omitted.
-enum CompletionStyleFlag { Detailed, Bundled };
-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")));
+opt<Path> ResourceDir{
+    "resource-dir",
+    cat(CompileCommands),
+    desc("Directory for system clang headers"),
+    init(""),
+    Hidden,
+};
+
+list<std::string> 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 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);
-
-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), llvm::cl::Hidden);
+opt<bool> 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 llvm::cl::opt<bool>
-    PrettyPrint("pretty", llvm::cl::desc("Pretty-print JSON output"),
-                llvm::cl::init(false));
-
-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>
-    Test("lit-test",
-         llvm::cl::desc("Abbreviation for -input-style=delimited -pretty -sync "
-                        "-enable-test-scheme -log=verbose."
-                        "Intended to simplify lit tests"),
-         llvm::cl::init(false), llvm::cl::Hidden);
+opt<bool> ShowOrigins{
+    "debug-origin",
+    cat(Features),
+    desc("Show origins of completion items"),
+    init(CodeCompleteOptions().ShowOrigins),
+    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);
+opt<bool> EnableBackgroundIndex{
+    "background-index",
+    cat(Features),
+    desc("Index project code in the background and persist index on disk. "
+         "Experimental"),
+    init(true),
+};
 
-enum PCHStorageFlag { Disk, Memory };
-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));
+opt<bool> EnableClangTidy{
+    "clang-tidy",
+    cat(Features),
+    desc("Enable clang-tidy diagnostics"),
+    init(true),
+};
 
-static llvm::cl::opt<int> LimitResults(
-    "limit-results",
-    llvm::cl::desc("Limit the number of results returned by clangd. "
-                   "0 means no limit (default=100)"),
-    llvm::cl::init(100));
-
-static llvm::cl::opt<bool>
-    Sync("sync", llvm::cl::desc("Parse on main thread. If set, -j is ignored"),
-         llvm::cl::init(false), llvm::cl::Hidden);
-
-static llvm::cl::opt<Path>
-    ResourceDir("resource-dir",
-                llvm::cl::desc("Directory for system clang headers"),
-                llvm::cl::init(""), llvm::cl::Hidden);
+opt<std::string> 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(""),
+};
 
-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);
+opt<CodeCompleteOptions::CodeCompletionParse> 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 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);
+// FIXME: also support "plain" style where signatures are always omitted.
+enum CompletionStyleFlag { Detailed, Bundled };
+opt<CompletionStyleFlag> 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 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<bool> ShowOrigins(
-    "debug-origin", llvm::cl::desc("Show origins of completion items"),
-    llvm::cl::init(CodeCompleteOptions().ShowOrigins), llvm::cl::Hidden);
+opt<std::string> 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 llvm::cl::opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion(
+opt<bool> 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,
+};
+
+opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion{
     "header-insertion",
-    llvm::cl::desc("Add #include directives when accepting code completions"),
-    llvm::cl::init(CodeCompleteOptions().InsertIncludes),
-    llvm::cl::values(
+    cat(Features),
+    desc("Add #include directives when accepting code completions"),
+    init(CodeCompleteOptions().InsertIncludes),
+    values(
         clEnumValN(CodeCompleteOptions::IWYU, "iwyu",
                    "Include what you use. "
                    "Insert the owning header for top-level symbols, unless the "
@@ -165,118 +202,173 @@ static llvm::cl::opt<CodeCompleteOptions
                    "forward-declared"),
         clEnumValN(
             CodeCompleteOptions::NeverInsert, "never",
-            "Never insert #include directives as part of code completion")));
+            "Never insert #include directives as part of code completion")),
+};
 
-static llvm::cl::opt<bool> HeaderInsertionDecorators(
+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));
+    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),
+};
+
+opt<bool> HiddenFeatures{
+    "hidden-features",
+    cat(Features),
+    desc("Enable hidden features mostly useful to clangd developers"),
+    init(false),
+    Hidden,
+};
 
-static llvm::cl::opt<Path> IndexFile(
+opt<bool> IncludeIneligibleResults{
+    "include-ineligible-results",
+    cat(Features),
+    desc("Include ineligible completion results (e.g. private members)"),
+    init(CodeCompleteOptions().IncludeIneligibleResults),
+    Hidden,
+};
+
+opt<bool> 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<int> LimitResults{
+    "limit-results",
+    cat(Features),
+    desc("Limit the number of results returned by clangd. "
+         "0 means no limit (default=100)"),
+    init(100),
+};
+
+opt<bool> SuggestMissingIncludes{
+    "suggest-missing-includes",
+    cat(Features),
+    desc("Attempts to fix diagnostic errors caused by missing "
+         "includes using index"),
+    init(true),
+};
+
+list<std::string> TweakList{
+    "tweaks",
+    cat(Features),
+    desc("Specify a list of Tweaks to enable (only for clangd developers)."),
+    Hidden,
+    CommaSeparated,
+};
+
+opt<unsigned> WorkerThreadsCount{
+    "j",
+    cat(Misc),
+    desc("Number of async workers used by clangd"),
+    init(getDefaultAsyncThreadsCount()),
+};
+
+opt<Path> IndexFile{
     "index-file",
-    llvm::cl::desc(
+    cat(Misc),
+    desc(
         "Index file to build the static index. The file must have been created "
         "by a compatible clangd-indexer\n"
         "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(true));
+    init(""),
+    Hidden,
+};
 
-enum CompileArgsFrom { LSPCompileArgs, FilesystemCompileArgs };
-static llvm::cl::opt<CompileArgsFrom> CompileArgsFrom(
-    "compile_args_from", llvm::cl::desc("The source of compile commands"),
-    llvm::cl::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")),
-    llvm::cl::init(FilesystemCompileArgs), llvm::cl::Hidden);
+opt<bool> 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,
+};
 
-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),
-    llvm::cl::Hidden);
+enum PCHStorageFlag { Disk, Memory };
+opt<PCHStorageFlag> 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 llvm::cl::opt<std::string> ClangTidyChecks(
-    "clang-tidy-checks",
-    llvm::cl::desc(
-        "List of clang-tidy checks to run (this will override "
-        ".clang-tidy files). Only meaningful when -clang-tidy flag is on"),
-    llvm::cl::init(""));
-
-static llvm::cl::opt<bool>
-    EnableClangTidy("clang-tidy",
-                    llvm::cl::desc("Enable clang-tidy diagnostics"),
-                    llvm::cl::init(true));
-
-static llvm::cl::opt<std::string>
-    FallbackStyle("fallback-style",
-                  llvm::cl::desc("clang-format style to apply by default when "
-                                 "no .clang-format file is found"),
-                  llvm::cl::init(clang::format::DefaultFallbackStyle));
+opt<bool> Sync{
+    "sync",
+    cat(Misc),
+    desc("Parse on main thread. If set, -j is ignored"),
+    init(false),
+    Hidden,
+};
 
-static llvm::cl::opt<bool> SuggestMissingIncludes(
-    "suggest-missing-includes",
-    llvm::cl::desc("Attempts to fix diagnostic errors caused by missing "
-                   "includes using index"),
-    llvm::cl::init(true));
+opt<JSONStreamStyle> 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 llvm::cl::opt<OffsetEncoding> ForceOffsetEncoding(
-    "offset-encoding",
-    llvm::cl::desc("Force the offsetEncoding used for character positions. "
-                   "This bypasses negotiation via client capabilities"),
-    llvm::cl::values(clEnumValN(OffsetEncoding::UTF8, "utf-8",
-                                "Offsets are in UTF-8 bytes"),
-                     clEnumValN(OffsetEncoding::UTF16, "utf-16",
-                                "Offsets are in UTF-16 code units")),
-    llvm::cl::init(OffsetEncoding::UnsupportedEncoding));
-
-static llvm::cl::opt<CodeCompleteOptions::CodeCompletionParse>
-    CodeCompletionParse(
-        "completion-parse",
-        llvm::cl::desc("Whether the clang-parser is used for code-completion"),
-        llvm::cl::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")),
-        llvm::cl::init(CodeCompleteOptions().RunParser), llvm::cl::Hidden);
+opt<bool> EnableTestScheme{
+    "enable-test-uri-scheme",
+    cat(Protocol),
+    desc("Enable 'test:' URI scheme. Only use in lit tests"),
+    init(false),
+    Hidden,
+};
 
-static llvm::cl::opt<bool> HiddenFeatures(
-    "hidden-features",
-    llvm::cl::desc("Enable hidden features mostly useful to clangd developers"),
-    llvm::cl::init(false), llvm::cl::Hidden);
+opt<Path> InputMirrorFile{
+    "input-mirror-file",
+    cat(Protocol),
+    desc("Mirror all LSP input to the specified file. Useful for debugging"),
+    init(""),
+    Hidden,
+};
 
-static llvm::cl::list<std::string> QueryDriverGlobs(
-    "query-driver",
-    llvm::cl::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++-*"),
-    llvm::cl::CommaSeparated);
+opt<Logger::Level> 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 llvm::cl::list<std::string> TweakList(
-    "tweaks",
-    llvm::cl::desc(
-        "Specify a list of Tweaks to enable (only for clangd developers)."),
-    llvm::cl::Hidden, llvm::cl::CommaSeparated);
+opt<OffsetEncoding> ForceOffsetEncoding{
+    "offset-encoding",
+    cat(Protocol),
+    desc("Force the offsetEncoding used for character positions. "
+         "This bypasses negotiation via client capabilities"),
+    values(
+        clEnumValN(OffsetEncoding::UTF8, "utf-8", "Offsets are in UTF-8 bytes"),
+        clEnumValN(OffsetEncoding::UTF16, "utf-16",
+                   "Offsets are in UTF-16 code units")),
+    init(OffsetEncoding::UnsupportedEncoding),
+};
 
-namespace {
+opt<bool> PrettyPrint{
+    "pretty",
+    cat(Protocol),
+    desc("Pretty-print JSON output"),
+    init(false),
+};
 
 /// \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
@@ -342,14 +434,19 @@ int main(int argc, char *argv[]) {
   llvm::cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
     OS << clang::getClangToolFullVersion("clangd") << "\n";
   });
-  llvm::cl::ParseCommandLineOptions(
-      argc, argv,
-      "clangd is a language server that provides IDE-like features to editors. "
-      "\n\nIt should be used via an editor plugin rather than invoked "
-      "directly. "
-      "For more information, see:"
-      "\n\thttps://clang.llvm.org/extra/clangd.html"
-      "\n\thttps://microsoft.github.io/language-server-protocol/");
+  const char *FlagsEnvVar = "CLANGD_FLAGS";
+  const char *Overview =
+      R"(clangd is a language server that provides IDE-like features to editors.
+
+It should be used via an editor plugin rather than invoked directly. For more information, see:
+	https://clang.llvm.org/extra/clangd/
+	https://microsoft.github.io/language-server-protocol/
+
+clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment variable.
+)";
+  llvm::cl::HideUnrelatedOptions(ClangdCategories);
+  llvm::cl::ParseCommandLineOptions(argc, argv, Overview,
+                                    /*Errs=*/nullptr, FlagsEnvVar);
   if (Test) {
     Sync = true;
     InputStyle = JSONStreamStyle::Delimited;
@@ -414,11 +511,29 @@ int main(int argc, char *argv[]) {
   if (Tracer)
     TracingSession.emplace(*Tracer);
 
+  // If a user ran `clangd` in a terminal without redirecting anything,
+  // it's somewhat likely they're confused about how to use clangd.
+  // Show them the help overview, which explains.
+  if (llvm::outs().is_displayed() && llvm::errs().is_displayed())
+    llvm::errs() << Overview << "\n";
   // Use buffered stream to stderr (we still flush each log message). Unbuffered
   // stream can cause significant (non-deterministic) latency for the logger.
   llvm::errs().SetBuffered();
   StreamLogger Logger(llvm::errs(), LogLevel);
   LoggingSession LoggingSession(Logger);
+  // Write some initial logs before we start doing any real work.
+  log("{0}", clang::getClangToolFullVersion("clangd"));
+  {
+    SmallString<128> CWD;
+    if (auto Err = llvm::sys::fs::current_path(CWD))
+      log("Working directory unknown: {0}", Err.message());
+    else
+      log("Working directory: {0}", CWD);
+  }
+  for (int I = 0; I < argc; ++I)
+    log("argv[{0}]: {1}", I, argv[I]);
+  if (auto EnvFlags = llvm::sys::Process::GetEnv(FlagsEnvVar))
+    log("{0}: {1}", FlagsEnvVar, *EnvFlags);
 
   // If --compile-commands-dir arg was invoked, check value and override default
   // path.
@@ -497,12 +612,14 @@ int main(int argc, char *argv[]) {
   std::unique_ptr<Transport> TransportLayer;
   if (getenv("CLANGD_AS_XPC_SERVICE")) {
 #if CLANGD_BUILD_XPC
+    log("Starting LSP over XPC service");
     TransportLayer = newXPCTransport();
 #else
     llvm::errs() << "This clangd binary wasn't built with XPC support.\n";
     return (int)ErrorResultCode::CantRunAsXPCService;
 #endif
   } else {
+    log("Starting LSP over stdin/stdout");
     TransportLayer = newJSONTransport(
         stdin, llvm::outs(),
         InputMirrorStream ? InputMirrorStream.getPointer() : nullptr,




More information about the llvm-branch-commits mailing list