[llvm-branch-commits] [clang-tools-extra] 7e506b3 - [clangd] Allow diagnostics to be suppressed with configuration

2021-01-25 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-25T15:59:07+01:00
New Revision: 7e506b30a1e1500c3b0b54fba88ea664bc4232e5

URL: 
https://github.com/llvm/llvm-project/commit/7e506b30a1e1500c3b0b54fba88ea664bc4232e5
DIFF: 
https://github.com/llvm/llvm-project/commit/7e506b30a1e1500c3b0b54fba88ea664bc4232e5.diff

LOG: [clangd] Allow diagnostics to be suppressed with configuration

This has been specifically requested:
  https://github.com/clangd/vscode-clangd/issues/114
and various issues can be addressed with this as a workaround, e.g.:
  https://github.com/clangd/clangd/issues/662

Differential Revision: https://reviews.llvm.org/D95349

Added: 


Modified: 
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/Diagnostics.cpp
clang-tools-extra/clangd/Diagnostics.h
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index 79e94ef6fe37..675e721c7e64 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -28,6 +28,7 @@
 #include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
 #include 
 #include 
 
@@ -77,6 +78,12 @@ struct Config {
 llvm::Optional External;
   } Index;
 
+  /// Controls warnings and errors when parsing code.
+  struct {
+bool SuppressAll = false;
+llvm::StringSet<> Suppress;
+  } Diagnostics;
+
   /// Style of the codebase.
   struct {
 // Namespaces that should always be fully qualified, meaning no "using"

diff  --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 2040ea4649fe..f2e6d544e6c9 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -27,6 +27,7 @@
 #include "Config.h"
 #include "ConfigFragment.h"
 #include "ConfigProvider.h"
+#include "Diagnostics.h"
 #include "Features.inc"
 #include "TidyProvider.h"
 #include "support/Logger.h"
@@ -187,6 +188,7 @@ struct FragmentCompiler {
 compile(std::move(F.If));
 compile(std::move(F.CompileFlags));
 compile(std::move(F.Index));
+compile(std::move(F.Diagnostics));
 compile(std::move(F.ClangTidy));
   }
 
@@ -328,6 +330,27 @@ struct FragmentCompiler {
 });
   }
 
+  void compile(Fragment::DiagnosticsBlock &&F) {
+std::vector Normalized;
+for (const auto &Suppressed : F.Suppress) {
+  if (*Suppressed == "*") {
+Out.Apply.push_back([&](const Params &, Config &C) {
+  C.Diagnostics.SuppressAll = true;
+  C.Diagnostics.Suppress.clear();
+});
+return;
+  }
+  Normalized.push_back(normalizeSuppressedCode(*Suppressed));
+}
+if (!Normalized.empty())
+  Out.Apply.push_back([Normalized](const Params &, Config &C) {
+if (C.Diagnostics.SuppressAll)
+  return;
+for (llvm::StringRef N : Normalized)
+  C.Diagnostics.Suppress.insert(N);
+  });
+  }
+
   void compile(Fragment::StyleBlock &&F) {
 if (!F.FullyQualifiedNamespaces.empty()) {
   std::vector FullyQualifiedNamespaces;

diff  --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index 0e4ce638fc72..c491ec5ee68c 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -181,6 +181,24 @@ struct Fragment {
   };
   IndexBlock Index;
 
+  /// Controls behavior of diagnostics (errors and warnings).
+  struct DiagnosticsBlock {
+/// Diagnostic codes that should be suppressed.
+///
+/// Valid values are:
+/// - *, to disable all diagnostics
+/// - diagnostic codes exposed by clangd (e.g unknown_type, 
-Wunused-result)
+/// - clang internal diagnostic codes (e.g. err_unknown_type)
+/// - warning categories (e.g. unused-result)
+/// - clang-tidy check names (e.g. bugprone-narrowing-conversions)
+///
+/// This is a simple filter. Diagnostics can be controlled in other ways
+/// (e.g. by disabling a clang-tidy check, or the -Wunused compile flag).
+/// This often has other advantages, such as skipping some analysis.
+std::vector> Suppress;
+  };
+  DiagnosticsBlock Diagnostics;
+
   // Describes the style of the codebase, beyond formatting.
   struct StyleBlock {
 // Namespaces that should always be fully qualified, meaning no "using"
@@ -195,6 +213,7 @@ struct Fragment {
   ///
   /// The settings are merged with any settings found in .clang-tidy
   /// configiration files with these ones taking precedence.
+  // FIXME: move this to Diagnostics.Tidy.
   s

[llvm-branch-commits] [clang-tools-extra] 67d6fbe - [clangd] Release notes for 12.x

2021-02-22 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-02-22T22:06:19+01:00
New Revision: 67d6fbe0f157ba78e8131964d60155dc1090f409

URL: 
https://github.com/llvm/llvm-project/commit/67d6fbe0f157ba78e8131964d60155dc1090f409
DIFF: 
https://github.com/llvm/llvm-project/commit/67d6fbe0f157ba78e8131964d60155dc1090f409.diff

LOG: [clangd] Release notes for 12.x

Added: 


Modified: 
clang-tools-extra/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 2960aad5a556..64b3d224ff6f 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -47,6 +47,9 @@ Major New Features
 Improvements to clangd
 --
 
+Performance
+^^^
+
 - clangd's memory usage is significantly reduced on most Linux systems.
   In particular, memory usage should not increase dramatically over time.
 
@@ -59,6 +62,172 @@ Improvements to clangd
   systems can disable this using ``--malloc_trim=0`` or the CMake flag
   ``-DCLANGD_MALLOC_TRIM=0``.
 
+- Added the `$/memoryUsage request
+  `_: an LSP extension.
+  This provides a breakdown of the memory clangd thinks it is using (excluding
+  malloc overhead etc). The clangd VSCode extension supports showing the memory
+  usage tree.
+
+Parsing and selection
+^
+
+- Improved navigation of broken code in C using Recovery AST. (This has been
+  enabled for C++ since clangd 11).
+
+- Types are understood more often in broken code. (This is the first release
+  where Recovery AST preserves speculated types).
+
+- Heuristic resolution for dependent names in templates.
+
+Code completion
+^^^
+
+- Higher priority for symbols that were already used in this file, and symbols
+  from namespaces mentioned in this file. (Estimated 3% accuracy improvement)
+
+- Introduced a ranking algorithm trained on snippets from a large C++ codebase.
+  Use the flag ``--ranking-model=decision_forest`` to try this (Estimated 6%
+  accuracy improvement). This mode is likely to become the default in future.
+
+  Note: this is a generic model, not specialized for your code. clangd does not
+  collect any data from your code to train code completion.
+
+- Signature help works with functions with template-dependent parameter types.
+
+Go to definition
+
+
+- Selecting an ``auto`` or ``decltype`` keyword will attempt to navigate to
+  a definition of the deduced type.
+
+- Improved handling of aliases: navigate to the underlying entity more often.
+
+- Better understanding of declaration vs definition for Objective-C classes and
+  protocols.
+
+- Selecting a pure-virtual method shows its overrides.
+
+Find references
+^^^
+
+- Indexes are smarter about not returning stale references when code is 
deleted.
+
+- References in implementation files are always indexed, so results should be
+  more complete.
+
+- Find-references on a virtual method shows references to overridden methods.
+
+New navigation features
+^^^
+
+- Call hierarchy (``textDocument/callHierarchy``) is supported.
+  Only incoming calls are available.
+
+- Go to implementation (``textDocument/implementation``) is supported on
+  abstract classes, and on virtual methods.
+
+- Symbol search (``workspace/symbol``) queries may be partially qualified.
+  That is, typing ``b::Foo`` will match the symbol ``a::b::c::Foo``.
+
+Refactoring
+^^^
+
+- New refactoring: populate ``switch`` statement with cases.
+  (This acts as a fix for the ``-Wswitch-enum`` warning).
+
+- Renaming templates is supported, and many other complex cases were fixed.
+
+- Attempting to rename to an invalid or conflicting name can produce an error
+  message rather than broken code. (Not all cases are detected!)
+
+- The accuracy of many code actions has been improved.
+
+Hover
+^
+
+- Hovers for ``auto`` and ``decltype`` show the type in the same style as other
+  hovers. ``this`` is also now supported.
+
+- Displayed type names are more consistent and idiomatic.
+
+Semantic highlighting
+^
+
+- Inactive preprocessor regions (``#ifdef``) are highlighted as comments.
+
+- clangd 12 is the last release with support for the non-standard
+  ``textDocument/semanticHighlights`` notification. Clients sholud migrate to
+  the ``textDocument/semanticTokens`` request added in LSP 3.16.
+
+Remote index (alpha)
+
+
+- clangd can now connect to a remote index server instead of building a project
+  index locally. This saves resources in large codebases that are slow to 
index.
+
+- The server program is ``clangd-index-server``, and it consumes index files
+  produced by ``clangd-indexer``.
+
+- This feature requires clangd to be built with the CMake flag
+  ``-DCLANGD_ENABLE_REMOTE=On``, which requires GRPC lib

[llvm-branch-commits] [clang-tools-extra] 22a34e0 - [clangd] Support configuration of inlay hints.

2022-01-10 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2022-01-10T10:26:48+01:00
New Revision: 22a34e01066004c9bd8d7ad418df90b8fbcb3749

URL: 
https://github.com/llvm/llvm-project/commit/22a34e01066004c9bd8d7ad418df90b8fbcb3749
DIFF: 
https://github.com/llvm/llvm-project/commit/22a34e01066004c9bd8d7ad418df90b8fbcb3749.diff

LOG: [clangd] Support configuration of inlay hints.

The idea is that the feature will always be advertised at the LSP level, but
depending on config we'll return partial or no responses.

We try to avoid doing the analysis for hints we're not going to return.

Examples of syntax:
```
InlayHints:
  Enabled: No
---
InlayHints:
  ParameterNames: No
---
InlayHints:
  ParameterNames: Yes
  DeducedTypes: Yes
```

Differential Revision: https://reviews.llvm.org/D116713

Added: 


Modified: 
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/InlayHints.cpp
clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
clang-tools-extra/clangd/unittests/InlayHintTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index 38fc93fa361c..952626db31e4 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -122,6 +122,15 @@ struct Config {
 /// Whether hover show a.k.a type.
 bool ShowAKA = false;
   } Hover;
+
+  struct {
+/// If false, inlay hints are completely disabled.
+bool Enabled = true;
+
+// Whether specific categories of hints are enabled.
+bool Parameters = true;
+bool DeducedTypes = true;
+  } InlayHints;
 };
 
 } // namespace clangd

diff  --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 18afdeb3cb5c..a606b98a2dba 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -197,6 +197,7 @@ struct FragmentCompiler {
 compile(std::move(F.Diagnostics));
 compile(std::move(F.Completion));
 compile(std::move(F.Hover));
+compile(std::move(F.InlayHints));
   }
 
   void compile(Fragment::IfBlock &&F) {
@@ -526,6 +527,22 @@ struct FragmentCompiler {
 }
   }
 
+  void compile(Fragment::InlayHintsBlock &&F) {
+if (F.Enabled)
+  Out.Apply.push_back([Value(**F.Enabled)](const Params &, Config &C) {
+C.InlayHints.Enabled = Value;
+  });
+if (F.ParameterNames)
+  Out.Apply.push_back(
+  [Value(**F.ParameterNames)](const Params &, Config &C) {
+C.InlayHints.Parameters = Value;
+  });
+if (F.DeducedTypes)
+  Out.Apply.push_back([Value(**F.DeducedTypes)](const Params &, Config &C) 
{
+C.InlayHints.DeducedTypes = Value;
+  });
+  }
+
   constexpr static llvm::SourceMgr::DiagKind Error = llvm::SourceMgr::DK_Error;
   constexpr static llvm::SourceMgr::DiagKind Warning =
   llvm::SourceMgr::DK_Warning;

diff  --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index 31c4636efa0b..d165b6305aa5 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -283,6 +283,18 @@ struct Fragment {
 llvm::Optional> ShowAKA;
   };
   HoverBlock Hover;
+
+  /// Configures labels shown inline with the code.
+  struct InlayHintsBlock {
+/// Enables/disables the inlay-hints feature.
+llvm::Optional> Enabled;
+
+/// Show parameter names before function arguments.
+llvm::Optional> ParameterNames;
+/// Show deduced types for `auto`.
+llvm::Optional> DeducedTypes;
+  };
+  InlayHintsBlock InlayHints;
 };
 
 } // namespace config

diff  --git a/clang-tools-extra/clangd/ConfigYAML.cpp 
b/clang-tools-extra/clangd/ConfigYAML.cpp
index 0487c3281576..04c0c633a3bb 100644
--- a/clang-tools-extra/clangd/ConfigYAML.cpp
+++ b/clang-tools-extra/clangd/ConfigYAML.cpp
@@ -66,6 +66,7 @@ class Parser {
 Dict.handle("Diagnostics", [&](Node &N) { parse(F.Diagnostics, N); });
 Dict.handle("Completion", [&](Node &N) { parse(F.Completion, N); });
 Dict.handle("Hover", [&](Node &N) { parse(F.Hover, N); });
+Dict.handle("InlayHints", [&](Node &N) { parse(F.InlayHints, N); });
 Dict.parse(N);
 return !(N.failed() || HadError);
   }
@@ -199,12 +200,8 @@ class Parser {
   void parse(Fragment::CompletionBlock &F, Node &N) {
 DictParser Dict("Completion", this);
 Dict.handle("AllScopes", [&](Node &N) {
-  if (auto Value = scalarValue(N, "AllScopes")) {
-if (auto AllScopes = llvm::yaml::parseBool(**Value))
-  F.AllScopes = *AllScopes;
-else
-  warning("AllScopes should be a boolean", N);
-  }
+  if (auto AllScopes = boolValue(N, "AllScopes"))
+F.AllScopes = *AllScopes;
 });
 Dict.parse(N);
   }
@@ -212,12 +209,25 @@ class Parse

[llvm-branch-commits] [clang-tools-extra] 90164ba - [clangd] Split out a base class for delegating GlobalCompilationDatabases. NFC

2021-01-13 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-13T16:20:33+01:00
New Revision: 90164ba957a2532daef6515d7114af69eca025a7

URL: 
https://github.com/llvm/llvm-project/commit/90164ba957a2532daef6515d7114af69eca025a7
DIFF: 
https://github.com/llvm/llvm-project/commit/90164ba957a2532daef6515d7114af69eca025a7.diff

LOG: [clangd] Split out a base class for delegating GlobalCompilationDatabases. 
NFC

This prepares for adding another delegatable method (blockUntilIdle) to GCDB.

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h
clang-tools-extra/clangd/QueryDriverDatabase.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index 86375fa11d3b..9a74ef0d5c2f 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -556,13 +556,8 @@ 
DirectoryBasedGlobalCompilationDatabase::getProjectInfo(PathRef File) const {
 OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base,
std::vector FallbackFlags,
tooling::ArgumentsAdjuster Adjuster)
-: Base(Base), ArgsAdjuster(std::move(Adjuster)),
-  FallbackFlags(std::move(FallbackFlags)) {
-  if (Base)
-BaseChanged = Base->watch([this](const std::vector Changes) {
-  OnCommandChanged.broadcast(Changes);
-});
-}
+: DelegatingCDB(Base), ArgsAdjuster(std::move(Adjuster)),
+  FallbackFlags(std::move(FallbackFlags)) {}
 
 llvm::Optional
 OverlayCDB::getCompileCommand(PathRef File) const {
@@ -573,8 +568,8 @@ OverlayCDB::getCompileCommand(PathRef File) const {
 if (It != Commands.end())
   Cmd = It->second;
   }
-  if (!Cmd && Base)
-Cmd = Base->getCompileCommand(File);
+  if (!Cmd)
+Cmd = DelegatingCDB::getCompileCommand(File);
   if (!Cmd)
 return llvm::None;
   if (ArgsAdjuster)
@@ -583,8 +578,7 @@ OverlayCDB::getCompileCommand(PathRef File) const {
 }
 
 tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const {
-  auto Cmd = Base ? Base->getFallbackCommand(File)
-  : GlobalCompilationDatabase::getFallbackCommand(File);
+  auto Cmd = DelegatingCDB::getFallbackCommand(File);
   std::lock_guard Lock(Mutex);
   Cmd.CommandLine.insert(Cmd.CommandLine.end(), FallbackFlags.begin(),
  FallbackFlags.end());
@@ -609,13 +603,37 @@ void OverlayCDB::setCompileCommand(
   OnCommandChanged.broadcast({CanonPath});
 }
 
-llvm::Optional OverlayCDB::getProjectInfo(PathRef File) const {
-  // It wouldn't make much sense to treat files with overridden commands
-  // specially when we can't do the same for the (unknown) local headers they
-  // include or changing behavior mid-air after receiving an override.
+DelegatingCDB::DelegatingCDB(const GlobalCompilationDatabase *Base)
+: Base(Base) {
   if (Base)
-return Base->getProjectInfo(File);
-  return llvm::None;
+BaseChanged = Base->watch([this](const std::vector Changes) {
+  OnCommandChanged.broadcast(Changes);
+});
+}
+
+DelegatingCDB::DelegatingCDB(std::unique_ptr Base)
+: DelegatingCDB(Base.get()) {
+  BaseOwner = std::move(Base);
 }
+
+llvm::Optional
+DelegatingCDB::getCompileCommand(PathRef File) const {
+  if (!Base)
+return llvm::None;
+  return Base->getCompileCommand(File);
+}
+
+llvm::Optional DelegatingCDB::getProjectInfo(PathRef File) const {
+  if (!Base)
+return llvm::None;
+  return Base->getProjectInfo(File);
+}
+
+tooling::CompileCommand DelegatingCDB::getFallbackCommand(PathRef File) const {
+  if (!Base)
+return GlobalCompilationDatabase::getFallbackCommand(File);
+  return Base->getFallbackCommand(File);
+}
+
 } // namespace clangd
 } // namespace clang

diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.h 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.h
index 9fb6f15f13d2..125bd77a5207 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.h
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.h
@@ -62,6 +62,25 @@ class GlobalCompilationDatabase {
   mutable CommandChanged OnCommandChanged;
 };
 
+// Helper class for implementing GlobalCompilationDatabases that wrap others.
+class DelegatingCDB : public GlobalCompilationDatabase {
+public:
+  DelegatingCDB(const GlobalCompilationDatabase *Base);
+  DelegatingCDB(std::unique_ptr Base);
+
+  llvm::Optional
+  getCompileCommand(PathRef File) const override;
+
+  llvm::Optional getProjectInfo(PathRef File) const override;
+
+  tooling::CompileCommand getFallbackCommand(PathRef File) const override;
+
+private:
+  const GlobalCompilationDatabase *Base;
+  std::unique_ptr BaseOwner;
+  CommandChanged::Subscription BaseChanged;
+};
+
 /// Gets compile args from tooling::CompilationDatabases built for parent
 /// directories.
 class Directo

[llvm-branch-commits] [clang-tools-extra] 66d5994 - [clangd] Explicitly avoid background-indexing the same file twice.

2021-01-13 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-13T17:29:30+01:00
New Revision: 66d5994bd38a9be4a0c05de2b69f88b64e6845ce

URL: 
https://github.com/llvm/llvm-project/commit/66d5994bd38a9be4a0c05de2b69f88b64e6845ce
DIFF: 
https://github.com/llvm/llvm-project/commit/66d5994bd38a9be4a0c05de2b69f88b64e6845ce.diff

LOG: [clangd] Explicitly avoid background-indexing the same file twice.

This used to implicitly never happen due to only discovering each CDB
once.

We may want to carefully support reindexing one day, but we need to do
it carefully (tricky tradeoffs) and it would need further support in
background indexer.

Making this explicit here rather than just turning off rebroadcast in
background index for a few reasons:
- allows *new* files in the same CDB to be indexed
- relying on bugs-at-a-distance cancelling each other out is bound to bite us
- gets us closer to actually supporting reindexing, which requires similar 
tracking

Differential Revision: https://reviews.llvm.org/D94503

Added: 


Modified: 
clang-tools-extra/clangd/index/Background.cpp
clang-tools-extra/clangd/index/Background.h
clang-tools-extra/clangd/index/BackgroundQueue.cpp
clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/index/Background.cpp 
b/clang-tools-extra/clangd/index/Background.cpp
index 1649bffea2ed..e4ce1f57ff2f 100644
--- a/clang-tools-extra/clangd/index/Background.cpp
+++ b/clang-tools-extra/clangd/index/Background.cpp
@@ -43,6 +43,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Threading.h"
+#include "llvm/Support/xxhash.h"
 
 #include 
 #include 
@@ -139,8 +140,8 @@ BackgroundQueue::Task BackgroundIndex::changedFilesTask(
  std::mt19937(std::random_device{}()));
 std::vector Tasks;
 Tasks.reserve(NeedsReIndexing.size());
-for (auto &Cmd : NeedsReIndexing)
-  Tasks.push_back(indexFileTask(std::move(Cmd)));
+for (const auto &File : NeedsReIndexing)
+  Tasks.push_back(indexFileTask(std::move(File)));
 Queue.append(std::move(Tasks));
   });
 
@@ -156,6 +157,7 @@ static llvm::StringRef 
filenameWithoutExtension(llvm::StringRef Path) {
 
 BackgroundQueue::Task BackgroundIndex::indexFileTask(std::string Path) {
   std::string Tag = filenameWithoutExtension(Path).str();
+  uint64_t Key = llvm::xxHash64(Path);
   BackgroundQueue::Task T([this, Path(std::move(Path))] {
 llvm::Optional WithProvidedContext;
 if (ContextProvider)
@@ -168,6 +170,7 @@ BackgroundQueue::Task 
BackgroundIndex::indexFileTask(std::string Path) {
   });
   T.QueuePri = IndexFile;
   T.Tag = std::move(Tag);
+  T.Key = Key;
   return T;
 }
 

diff  --git a/clang-tools-extra/clangd/index/Background.h 
b/clang-tools-extra/clangd/index/Background.h
index e8f9468889f2..fbcec7014957 100644
--- a/clang-tools-extra/clangd/index/Background.h
+++ b/clang-tools-extra/clangd/index/Background.h
@@ -76,6 +76,8 @@ class BackgroundQueue {
 llvm::ThreadPriority ThreadPri = llvm::ThreadPriority::Background;
 unsigned QueuePri = 0; // Higher-priority tasks will run first.
 std::string Tag;   // Allows priority to be boosted later.
+uint64_t Key = 0;  // If the key matches a previous task, drop this 
one.
+   // (in practice this means we never reindex a file).
 
 bool operator<(const Task &O) const { return QueuePri < O.QueuePri; }
   };
@@ -114,6 +116,7 @@ class BackgroundQueue {
 
 private:
   void notifyProgress() const; // Requires lock Mu
+  bool adjust(Task &T);
 
   std::mutex Mu;
   Stats Stat;
@@ -122,6 +125,7 @@ class BackgroundQueue {
   std::vector Queue; // max-heap
   llvm::StringMap Boosts;
   std::function OnProgress;
+  llvm::DenseSet SeenKeys;
 };
 
 // Builds an in-memory index by by running the static indexer action over

diff  --git a/clang-tools-extra/clangd/index/BackgroundQueue.cpp 
b/clang-tools-extra/clangd/index/BackgroundQueue.cpp
index 3262a2f46d38..b0dc2acca356 100644
--- a/clang-tools-extra/clangd/index/BackgroundQueue.cpp
+++ b/clang-tools-extra/clangd/index/BackgroundQueue.cpp
@@ -72,10 +72,24 @@ void BackgroundQueue::stop() {
   CV.notify_all();
 }
 
+// Tweaks the priority of a newly-enqueued task, or returns false to cancel it.
+bool BackgroundQueue::adjust(Task &T) {
+  // It is tempting to drop duplicates of queued tasks, and merely deprioritize
+  // duplicates of completed tasks (i.e. reindexing on CDB changes). But:
+  //  - the background indexer doesn't support reindexing well, e.g. staleness
+  //is checked at *enqueue* time only, and doesn't account for compile 
flags
+  //  - reindexing on compile flags is often a poor use of CPU in practice
+  if (T.Key && !SeenKeys.insert(T.Key).second)
+return false;
+  T.QueuePri = std::max(T.QueuePri, Boosts.lookup(T.Tag));
+  return true;
+}
+
 void BackgroundQueue::push(Task T) {
   {
  

[llvm-branch-commits] [clang-tools-extra] 466acd6 - [clangd] Avoid reallocating buffers for each message read:

2021-01-13 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-13T17:40:33+01:00
New Revision: 466acd694861138997d668a3f9cb29aa87bd316e

URL: 
https://github.com/llvm/llvm-project/commit/466acd694861138997d668a3f9cb29aa87bd316e
DIFF: 
https://github.com/llvm/llvm-project/commit/466acd694861138997d668a3f9cb29aa87bd316e.diff

LOG: [clangd] Avoid reallocating buffers for each message read:

 - reuse std::string we read messages into
 - when reading line-wise, use SmallVector<128> and read in chunks of 128
   (this affects headers, which are short, and tests, which don't matter)

Differential Revision: https://reviews.llvm.org/D93653

Added: 


Modified: 
clang-tools-extra/clangd/JSONTransport.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/JSONTransport.cpp 
b/clang-tools-extra/clangd/JSONTransport.cpp
index 662e5df4e27b..3e8caceda21c 100644
--- a/clang-tools-extra/clangd/JSONTransport.cpp
+++ b/clang-tools-extra/clangd/JSONTransport.cpp
@@ -10,6 +10,7 @@
 #include "support/Cancellation.h"
 #include "support/Logger.h"
 #include "support/Shutdown.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Errno.h"
 #include "llvm/Support/Error.h"
 #include 
@@ -99,6 +100,7 @@ class JSONTransport : public Transport {
   }
 
   llvm::Error loop(MessageHandler &Handler) override {
+std::string JSON; // Messages may be large, reuse same big buffer.
 while (!feof(In)) {
   if (shutdownRequested())
 return error(std::make_error_code(std::errc::operation_canceled),
@@ -106,14 +108,14 @@ class JSONTransport : public Transport {
   if (ferror(In))
 return llvm::errorCodeToError(
 std::error_code(errno, std::system_category()));
-  if (auto JSON = readRawMessage()) {
-if (auto Doc = llvm::json::parse(*JSON)) {
+  if (readRawMessage(JSON)) {
+if (auto Doc = llvm::json::parse(JSON)) {
   vlog(Pretty ? "<<< {0:2}\n" : "<<< {0}\n", *Doc);
   if (!handleMessage(std::move(*Doc), Handler))
 return llvm::Error::success(); // we saw the "exit" notification.
 } else {
   // Parse error. Log the raw message.
-  vlog("<<< {0}\n", *JSON);
+  vlog("<<< {0}\n", JSON);
   elog("JSON parse error: {0}", llvm::toString(Doc.takeError()));
 }
   }
@@ -136,12 +138,12 @@ class JSONTransport : public Transport {
   }
 
   // Read raw string messages from input stream.
-  llvm::Optional readRawMessage() {
-return Style == JSONStreamStyle::Delimited ? readDelimitedMessage()
-   : readStandardMessage();
+  bool readRawMessage(std::string &JSON) {
+return Style == JSONStreamStyle::Delimited ? readDelimitedMessage(JSON)
+   : readStandardMessage(JSON);
   }
-  llvm::Optional readDelimitedMessage();
-  llvm::Optional readStandardMessage();
+  bool readDelimitedMessage(std::string &JSON);
+  bool readStandardMessage(std::string &JSON);
 
   llvm::SmallVector OutputBuffer;
   std::FILE *In;
@@ -191,12 +193,14 @@ bool JSONTransport::handleMessage(llvm::json::Value 
Message,
 
 // Tries to read a line up to and including \n.
 // If failing, feof(), ferror(), or shutdownRequested() will be set.
-bool readLine(std::FILE *In, std::string &Out) {
-  static constexpr int BufSize = 1024;
+bool readLine(std::FILE *In, llvm::SmallVectorImpl &Out) {
+  // Big enough to hold any reasonable header line. May not fit content lines
+  // in delimited mode, but performance doesn't matter for that mode.
+  static constexpr int BufSize = 128;
   size_t Size = 0;
   Out.clear();
   for (;;) {
-Out.resize(Size + BufSize);
+Out.resize_for_overwrite(Size + BufSize);
 // Handle EINTR which is sent when a debugger attaches on some platforms.
 if (!retryAfterSignalUnlessShutdown(
 nullptr, [&] { return std::fgets(&Out[Size], BufSize, In); }))
@@ -216,14 +220,14 @@ bool readLine(std::FILE *In, std::string &Out) {
 // Returns None when:
 //  - ferror(), feof(), or shutdownRequested() are set.
 //  - Content-Length is missing or empty (protocol error)
-llvm::Optional JSONTransport::readStandardMessage() {
+bool JSONTransport::readStandardMessage(std::string &JSON) {
   // A Language Server Protocol message starts with a set of HTTP headers,
   // delimited  by \r\n, and terminated by an empty line (\r\n).
   unsigned long long ContentLength = 0;
-  std::string Line;
+  llvm::SmallString<128> Line;
   while (true) {
 if (feof(In) || ferror(In) || !readLine(In, Line))
-  return llvm::None;
+  return false;
 InMirror << Line;
 
 llvm::StringRef LineRef(Line);
@@ -258,14 +262,14 @@ llvm::Optional 
JSONTransport::readStandardMessage() {
 elog("Refusing to read message with long Content-Length: {0}. "
  "Expect protocol errors",
  ContentLength);
-return llvm::None;
+return false;
   }
   if (Conte

[llvm-branch-commits] [clang-tools-extra] 0bbc6a6 - [clangd] Remove some old CodeCompletion options that are never (un)set. NFC

2021-01-13 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-13T18:01:48+01:00
New Revision: 0bbc6a6bb643af69baaf85f7f380dbcfe1f5ad54

URL: 
https://github.com/llvm/llvm-project/commit/0bbc6a6bb643af69baaf85f7f380dbcfe1f5ad54
DIFF: 
https://github.com/llvm/llvm-project/commit/0bbc6a6bb643af69baaf85f7f380dbcfe1f5ad54.diff

LOG: [clangd] Remove some old CodeCompletion options that are never (un)set.  
NFC

Added: 


Modified: 
clang-tools-extra/clangd/CodeComplete.cpp
clang-tools-extra/clangd/CodeComplete.h
clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index 53c647a68788..b3b40022fbb2 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -277,7 +277,7 @@ struct CodeCompletionBuilder {
 CodeCompletionContext::Kind ContextKind,
 const CodeCompleteOptions &Opts,
 bool IsUsingDeclaration, tok::TokenKind NextTokenKind)
-  : ASTCtx(ASTCtx), ExtractDocumentation(Opts.IncludeComments),
+  : ASTCtx(ASTCtx),
 EnableFunctionArgSnippets(Opts.EnableFunctionArgSnippets),
 IsUsingDeclaration(IsUsingDeclaration), NextTokenKind(NextTokenKind) {
 add(C, SemaCCS);
@@ -393,7 +393,7 @@ struct CodeCompletionBuilder {
   S.SnippetSuffix = std::string(C.IndexResult->CompletionSnippetSuffix);
   S.ReturnType = std::string(C.IndexResult->ReturnType);
 }
-if (ExtractDocumentation && !Completion.Documentation) {
+if (!Completion.Documentation) {
   auto SetDoc = [&](llvm::StringRef Doc) {
 if (!Doc.empty()) {
   Completion.Documentation.emplace();
@@ -512,7 +512,6 @@ struct CodeCompletionBuilder {
   ASTContext *ASTCtx;
   CodeCompletion Completion;
   llvm::SmallVector Bundled;
-  bool ExtractDocumentation;
   bool EnableFunctionArgSnippets;
   // No snippets will be generated for using declarations and when the function
   // arguments are already present.
@@ -1765,8 +1764,8 @@ class CodeCompleteFlow {
 
 clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
   clang::CodeCompleteOptions Result;
-  Result.IncludeCodePatterns = EnableSnippets && IncludeCodePatterns;
-  Result.IncludeMacros = IncludeMacros;
+  Result.IncludeCodePatterns = EnableSnippets;
+  Result.IncludeMacros = true;
   Result.IncludeGlobals = true;
   // We choose to include full comments and not do doxygen parsing in
   // completion.

diff  --git a/clang-tools-extra/clangd/CodeComplete.h 
b/clang-tools-extra/clangd/CodeComplete.h
index ce8a2097a6d9..f7ac3c7e5aba 100644
--- a/clang-tools-extra/clangd/CodeComplete.h
+++ b/clang-tools-extra/clangd/CodeComplete.h
@@ -50,17 +50,6 @@ struct CodeCompleteOptions {
   /// b})).
   bool EnableSnippets = false;
 
-  /// Add code patterns to completion results.
-  /// If EnableSnippets is false, this options is ignored and code patterns 
will
-  /// always be omitted.
-  bool IncludeCodePatterns = true;
-
-  /// Add macros to code completion results.
-  bool IncludeMacros = true;
-
-  /// Add comments to code completion results, if available.
-  bool IncludeComments = true;
-
   /// Include results that are not legal completions in the current context.
   /// For example, private members are usually inaccessible.
   bool IncludeIneligibleResults = false;

diff  --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 76b193b49791..43a557d6c73e 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -315,8 +315,7 @@ void testAfterDotCompletion(clangd::CodeCompleteOptions 
Opts) {
   EXPECT_THAT(Results.Completions,
   Not(Contains(Kind(CompletionItemKind::Snippet;
   // Check documentation.
-  EXPECT_IFF(Opts.IncludeComments, Results.Completions,
- Contains(IsDocumented()));
+  EXPECT_THAT(Results.Completions, Contains(IsDocumented()));
 }
 
 void testGlobalScopeCompletion(clangd::CodeCompleteOptions Opts) {
@@ -356,14 +355,13 @@ void 
testGlobalScopeCompletion(clangd::CodeCompleteOptions Opts) {
 Has("index_func" /* our fake symbol doesn't include () */),
 Has("GlobalClass"), Has("IndexClass")));
   // A macro.
-  EXPECT_IFF(Opts.IncludeMacros, Results.Completions, Has("MACRO"));
+  EXPECT_THAT(Results.Completions, Has("MACRO"));
   // Local items. Must be present always.
   EXPECT_THAT(Results.Completions,
   AllOf(Has("local_var"), Has("LocalClass"),
 Contains(Kind(CompletionItemKind::Snippet;
   // Check documentation.
-  EXPECT_IFF(Opts.IncludeComments, Results.Completions,
- Contains(IsDocumented()));
+  EXPECT_THAT(Results.Completions, Contains(I

[llvm-branch-commits] [clang-tools-extra] 17fb21f - [clangd] Remove another option that was effectively always true. NFC

2021-01-14 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-14T17:19:47+01:00
New Revision: 17fb21f875f4aaf6ad2cf9499cb75d76588167f2

URL: 
https://github.com/llvm/llvm-project/commit/17fb21f875f4aaf6ad2cf9499cb75d76588167f2
DIFF: 
https://github.com/llvm/llvm-project/commit/17fb21f875f4aaf6ad2cf9499cb75d76588167f2.diff

LOG: [clangd] Remove another option that was effectively always true. NFC

Added: 


Modified: 
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/CodeComplete.h
clang-tools-extra/clangd/tool/ClangdMain.cpp
clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index d5e21cfb063e..4f3a47dff05d 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -243,15 +243,11 @@ void ClangdServer::codeComplete(PathRef File, Position 
Pos,
   // No speculation in Fallback mode, as it's supposed to be much faster
   // without compiling.
   vlog("Build for file {0} is not ready. Enter fallback mode.", File);
-} else {
-  if (CodeCompleteOpts.Index && CodeCompleteOpts.SpeculativeIndexRequest) {
-SpecFuzzyFind.emplace();
-{
-  std::lock_guard Lock(
-  CachedCompletionFuzzyFindRequestMutex);
-  SpecFuzzyFind->CachedReq =
-  CachedCompletionFuzzyFindRequestByFile[File];
-}
+} else if (CodeCompleteOpts.Index) {
+  SpecFuzzyFind.emplace();
+  {
+std::lock_guard 
Lock(CachedCompletionFuzzyFindRequestMutex);
+SpecFuzzyFind->CachedReq = 
CachedCompletionFuzzyFindRequestByFile[File];
   }
 }
 ParseInputs ParseInput{IP->Command, &TFS, IP->Contents.str()};

diff  --git a/clang-tools-extra/clangd/CodeComplete.h 
b/clang-tools-extra/clangd/CodeComplete.h
index f7ac3c7e5aba..ddcbd487ecc6 100644
--- a/clang-tools-extra/clangd/CodeComplete.h
+++ b/clang-tools-extra/clangd/CodeComplete.h
@@ -82,16 +82,6 @@ struct CodeCompleteOptions {
   /// Expose origins of completion items in the label (for debugging).
   bool ShowOrigins = false;
 
-  /// If set to true, this will send an asynchronous speculative index request,
-  /// based on the index request for the last code completion on the same file
-  /// and the filter text typed before the cursor, before sema code completion
-  /// is invoked. This can reduce the code completion latency (by roughly
-  /// latency of sema code completion) if the speculative request is the same 
as
-  /// the one generated for the ongoing code completion from sema. As a 
sequence
-  /// of code completions often have the same scopes and proximity paths etc,
-  /// this should be effective for a number of code completions.
-  bool SpeculativeIndexRequest = false;
-
   // Populated internally by clangd, do not set.
   /// If `Index` is set, it is used to augment the code completion
   /// results.

diff  --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp 
b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 9c75cafdb08e..d3859103b0f0 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -828,7 +828,6 @@ clangd accepts flags on the commandline, and in the 
CLANGD_FLAGS environment var
 Opts.CodeComplete.IncludeIndicator.Insert.clear();
 Opts.CodeComplete.IncludeIndicator.NoInsert.clear();
   }
-  Opts.CodeComplete.SpeculativeIndexRequest = Opts.StaticIndex;
   Opts.CodeComplete.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
   Opts.CodeComplete.AllScopes = AllScopesCompletion;
   Opts.CodeComplete.RunParser = CodeCompletionParse;

diff  --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 43a557d6c73e..9842bcb315e5 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -2339,7 +2339,6 @@ TEST(CompletionTest, EnableSpeculativeIndexRequest) {
 
   IndexRequestCollector Requests;
   Opts.Index = &Requests;
-  Opts.SpeculativeIndexRequest = true;
 
   auto CompleteAtPoint = [&](StringRef P) {
 cantFail(runCodeComplete(Server, File, Test.point(P), Opts));



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 4183999 - [clangd] Reduce logspam for CDB scanning

2021-01-14 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-14T23:55:02+01:00
New Revision: 4183999e0fe1ffbc8bdb2f06f2e5f210a0c94e35

URL: 
https://github.com/llvm/llvm-project/commit/4183999e0fe1ffbc8bdb2f06f2e5f210a0c94e35
DIFF: 
https://github.com/llvm/llvm-project/commit/4183999e0fe1ffbc8bdb2f06f2e5f210a0c94e35.diff

LOG: [clangd] Reduce logspam for CDB scanning

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index 9a74ef0d5c2f..d983f76e227f 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -350,7 +350,7 @@ bool 
DirectoryBasedGlobalCompilationDatabase::DirectoryCache::load(
 }
 // Don't log Error here, it's usually just "couldn't find ".
   }
-  vlog("No compilation database at {0}", Path);
+  dlog("No compilation database at {0}", Path);
   return true;
 }
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 536a1b0 - [clangd] Allow CDBs to have background work to block on.

2021-01-20 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-20T11:11:01+01:00
New Revision: 536a1b0ea21163eaee53652c527ea20cf45bc675

URL: 
https://github.com/llvm/llvm-project/commit/536a1b0ea21163eaee53652c527ea20cf45bc675
DIFF: 
https://github.com/llvm/llvm-project/commit/536a1b0ea21163eaee53652c527ea20cf45bc675.diff

LOG: [clangd] Allow CDBs to have background work to block on.

In preparation for moving DirectoryBasedCompilationDatabase broadcasting off
the main thread.

Differential Revision: https://reviews.llvm.org/D94603

Added: 


Modified: 
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index a76250fa168e7..0818d08811e0d 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -139,7 +139,8 @@ ClangdServer::Options::operator TUScheduler::Options() 
const {
 ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
const ThreadsafeFS &TFS, const Options &Opts,
Callbacks *Callbacks)
-: ConfigProvider(Opts.ConfigProvider), TFS(TFS), 
ServerCallbacks(Callbacks),
+: ConfigProvider(Opts.ConfigProvider), CDB(CDB), TFS(TFS),
+  ServerCallbacks(Callbacks),
   DynamicIdx(Opts.BuildDynamicSymbolIndex
  ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex,
  Opts.CollectMainFileRefs)
@@ -870,6 +871,7 @@ Context ClangdServer::createProcessingContext(PathRef File) 
const {
 LLVM_NODISCARD bool
 ClangdServer::blockUntilIdleForTest(llvm::Optional TimeoutSeconds) {
   return WorkScheduler.blockUntilIdle(timeoutSeconds(TimeoutSeconds)) &&
+ CDB.blockUntilIdle(timeoutSeconds(TimeoutSeconds)) &&
  (!BackgroundIdx ||
   BackgroundIdx->blockUntilIdleForTest(TimeoutSeconds));
 }

diff  --git a/clang-tools-extra/clangd/ClangdServer.h 
b/clang-tools-extra/clangd/ClangdServer.h
index ff2fc85781038..d10c54f402b42 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -362,6 +362,7 @@ class ClangdServer {
   Context createProcessingContext(PathRef) const;
   config::Provider *ConfigProvider = nullptr;
 
+  const GlobalCompilationDatabase &CDB;
   const ThreadsafeFS &TFS;
   Callbacks *ServerCallbacks = nullptr;
   mutable std::mutex ConfigDiagnosticsMu;

diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index fde4e56ac72d8..457cdef2bd8b5 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -636,5 +636,11 @@ tooling::CompileCommand 
DelegatingCDB::getFallbackCommand(PathRef File) const {
   return Base->getFallbackCommand(File);
 }
 
+bool DelegatingCDB::blockUntilIdle(Deadline D) const {
+  if (!Base)
+return true;
+  return Base->blockUntilIdle(D);
+}
+
 } // namespace clangd
 } // namespace clang

diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.h 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.h
index 125bd77a52073..d009905bbecf2 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.h
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.h
@@ -51,6 +51,10 @@ class GlobalCompilationDatabase {
   /// Clangd should treat the results as unreliable.
   virtual tooling::CompileCommand getFallbackCommand(PathRef File) const;
 
+  /// If the CDB does any asynchronous work, wait for it to complete.
+  /// For use in tests.
+  virtual bool blockUntilIdle(Deadline D) const { return true; }
+
   using CommandChanged = Event>;
   /// The callback is notified when files may have new compile commands.
   /// The argument is a list of full file paths.
@@ -75,6 +79,8 @@ class DelegatingCDB : public GlobalCompilationDatabase {
 
   tooling::CompileCommand getFallbackCommand(PathRef File) const override;
 
+  bool blockUntilIdle(Deadline D) const override;
+
 private:
   const GlobalCompilationDatabase *Base;
   std::unique_ptr BaseOwner;



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] de4ba70 - [clangd] Move DirBasedCDB broadcasting onto its own thread.

2021-01-20 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-20T11:22:55+01:00
New Revision: de4ba7073bd7e200aca704e6a26403e07bc246a5

URL: 
https://github.com/llvm/llvm-project/commit/de4ba7073bd7e200aca704e6a26403e07bc246a5
DIFF: 
https://github.com/llvm/llvm-project/commit/de4ba7073bd7e200aca704e6a26403e07bc246a5.diff

LOG: [clangd] Move DirBasedCDB broadcasting onto its own thread.

This is on the critical path (it blocks getting the compile command for
the first file).

It's not trivially fast: it involves processing all filenames in the CDB
and doing some IO to look for shadowing CDBs.

And we may make this slower soon - making CDB configurable implies evaluating
the config for each listed to see which ones really are owned by the
broadcasted CDB.

Differential Revision: https://reviews.llvm.org/D94606

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h
clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index 457cdef2bd8b..3ee2d2d5dec0 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -11,6 +11,7 @@
 #include "SourceCode.h"
 #include "support/Logger.h"
 #include "support/Path.h"
+#include "support/Threading.h"
 #include "support/ThreadsafeFS.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Tooling/ArgumentsAdjusters.h"
@@ -22,12 +23,15 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/VirtualFileSystem.h"
+#include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -357,7 +361,7 @@ bool 
DirectoryBasedGlobalCompilationDatabase::DirectoryCache::load(
 
 DirectoryBasedGlobalCompilationDatabase::
 DirectoryBasedGlobalCompilationDatabase(const Options &Opts)
-: Opts(Opts) {
+: Opts(Opts), Broadcaster(std::make_unique(*this)) {
   if (Opts.CompileCommandsDir)
 OnlyDirCache = std::make_unique(*Opts.CompileCommandsDir);
 }
@@ -472,25 +476,107 @@ DirectoryBasedGlobalCompilationDatabase::lookupCDB(
   Result.CDB = std::move(CDB);
   Result.PI.SourceRoot = DirCache->Path;
 
-  // FIXME: Maybe make the following part async, since this can block
-  // retrieval of compile commands.
   if (ShouldBroadcast)
 broadcastCDB(Result);
   return Result;
 }
 
-void DirectoryBasedGlobalCompilationDatabase::broadcastCDB(
-CDBLookupResult Result) const {
-  vlog("Broadcasting compilation database from {0}", Result.PI.SourceRoot);
-  assert(Result.CDB && "Trying to broadcast an invalid CDB!");
+// The broadcast thread announces files with new compile commands to the world.
+// Primarily this is used to enqueue them for background indexing.
+//
+// It's on a separate thread because:
+//  - otherwise it would block the first parse of the initial file
+//  - we need to enumerate all files in the CDB, of which there are many
+//  - we (will) have to evaluate config for every file in the CDB, which is 
slow
+class DirectoryBasedGlobalCompilationDatabase::BroadcastThread {
+  class Filter;
+  DirectoryBasedGlobalCompilationDatabase &Parent;
+
+  std::mutex Mu;
+  std::condition_variable CV;
+  // Shutdown flag (CV is notified after writing).
+  // This is atomic so that broadcasts can also observe it and abort early.
+  std::atomic ShouldStop = {false};
+  struct Task {
+CDBLookupResult Lookup;
+Context Ctx;
+  };
+  std::deque Queue;
+  llvm::Optional ActiveTask;
+  std::thread Thread; // Must be last member.
+
+  // Thread body: this is just the basic queue procesing boilerplate.
+  void run() {
+std::unique_lock Lock(Mu);
+while (true) {
+  bool Stopping = false;
+  CV.wait(Lock, [&] {
+return (Stopping = ShouldStop.load(std::memory_order_acquire)) ||
+   !Queue.empty();
+  });
+  if (Stopping) {
+Queue.clear();
+CV.notify_all();
+return;
+  }
+  ActiveTask = std::move(Queue.front());
+  Queue.pop_front();
 
-  std::vector AllFiles = Result.CDB->getAllFiles();
+  Lock.unlock();
+  {
+WithContext WithCtx(std::move(ActiveTask->Ctx));
+process(ActiveTask->Lookup);
+  }
+  Lock.lock();
+  ActiveTask.reset();
+  CV.notify_all();
+}
+  }
+
+  // Inspects a new CDB and broadcasts the files it owns.
+  void process(const CDBLookupResult &T);
+
+public:
+  BroadcastThread(DirectoryBasedGlobalCompilationDatabase &Parent)
+  : Parent(Parent), Thread([this] { run(); }) {}
+
+  void enqueue(CDBLookupResult Lookup) {
+ 

[llvm-branch-commits] [clang-tools-extra] e6be5c7 - [clangd] Remove the recovery-ast options.

2021-01-20 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-20T11:23:57+01:00
New Revision: e6be5c7cd6d227144f874623e2764890f80cad32

URL: 
https://github.com/llvm/llvm-project/commit/e6be5c7cd6d227144f874623e2764890f80cad32
DIFF: 
https://github.com/llvm/llvm-project/commit/e6be5c7cd6d227144f874623e2764890f80cad32.diff

LOG: [clangd] Remove the recovery-ast options.

These force a couple of flags or that are now on by default.
So the flags don't currently do anything unless the compile command has
-fno-recovery-ast explicitly.

(For turning recovery *off* for debugging we can inject the flag with config)

This leaves the command-line flags around with no effect, I'm planning to add
a "retired flag" mechanism shortly in a separate patch.

Differential Revision: https://reviews.llvm.org/D94724

Added: 


Modified: 
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/Compiler.cpp
clang-tools-extra/clangd/Compiler.h
clang-tools-extra/clangd/tool/ClangdMain.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 0818d08811e0..123d755f267e 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -147,8 +147,6 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase 
&CDB,
  : nullptr),
   ClangTidyProvider(Opts.ClangTidyProvider),
   SuggestMissingIncludes(Opts.SuggestMissingIncludes),
-  BuildRecoveryAST(Opts.BuildRecoveryAST),
-  PreserveRecoveryASTType(Opts.PreserveRecoveryASTType),
   WorkspaceRoot(Opts.WorkspaceRoot),
   // Pass a callback into `WorkScheduler` to extract symbols from a newly
   // parsed file and rebuild the file index synchronously each time an AST
@@ -214,8 +212,6 @@ void ClangdServer::addDocument(PathRef File, 
llvm::StringRef Contents,
   Inputs.Opts = std::move(Opts);
   Inputs.Index = Index;
   Inputs.ClangTidyProvider = ClangTidyProvider;
-  Inputs.Opts.BuildRecoveryAST = BuildRecoveryAST;
-  Inputs.Opts.PreserveRecoveryASTType = PreserveRecoveryASTType;
   bool NewFile = WorkScheduler.update(File, Inputs, WantDiags);
   // If we loaded Foo.h, we want to make sure Foo.cpp is indexed.
   if (NewFile && BackgroundIdx)
@@ -253,8 +249,6 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
 }
 ParseInputs ParseInput{IP->Command, &TFS, IP->Contents.str()};
 ParseInput.Index = Index;
-ParseInput.Opts.BuildRecoveryAST = BuildRecoveryAST;
-ParseInput.Opts.PreserveRecoveryASTType = PreserveRecoveryASTType;
 
 CodeCompleteOpts.MainFileSignals = IP->Signals;
 // FIXME(ibiryukov): even if Preamble is non-null, we may want to check
@@ -300,8 +294,6 @@ void ClangdServer::signatureHelp(PathRef File, Position Pos,
 
 ParseInputs ParseInput{IP->Command, &TFS, IP->Contents.str()};
 ParseInput.Index = Index;
-ParseInput.Opts.BuildRecoveryAST = BuildRecoveryAST;
-ParseInput.Opts.PreserveRecoveryASTType = PreserveRecoveryASTType;
 CB(clangd::signatureHelp(File, Pos, *PreambleData, ParseInput));
   };
 

diff  --git a/clang-tools-extra/clangd/ClangdServer.h 
b/clang-tools-extra/clangd/ClangdServer.h
index d10c54f402b4..832f8b04a11d 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -118,14 +118,6 @@ class ClangdServer {
 /// checks will be disabled.
 TidyProviderRef ClangTidyProvider;
 
-/// If true, force -frecovery-ast flag.
-/// If false, respect the value in clang.
-bool BuildRecoveryAST = false;
-
-/// If true, force -frecovery-ast-type flag.
-/// If false, respect the value in clang.
-bool PreserveRecoveryASTType = false;
-
 /// Clangd's workspace root. Relevant for "workspace" operations not bound
 /// to a particular file.
 /// FIXME: If not set, should use the current working directory.
@@ -388,11 +380,6 @@ class ClangdServer {
   // can be caused by missing includes (e.g. member access in incomplete type).
   bool SuggestMissingIncludes = false;
 
-  // If true, preserve expressions in AST for broken code.
-  bool BuildRecoveryAST = true;
-  // If true, preserve the type for recovery AST.
-  bool PreserveRecoveryASTType = false;
-
   // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
   llvm::StringMap>
   CachedCompletionFuzzyFindRequestByFile;

diff  --git a/clang-tools-extra/clangd/Compiler.cpp 
b/clang-tools-extra/clangd/Compiler.cpp
index 3d5c7113f852..bcae67d82050 100644
--- a/clang-tools-extra/clangd/Compiler.cpp
+++ b/clang-tools-extra/clangd/Compiler.cpp
@@ -85,11 +85,6 @@ buildCompilerInvocation(const ParseInputs &Inputs, 
clang::DiagnosticConsumer &D,
   // Don't crash on `#pragma clang __debug parser_crash`
   CI->getPreprocessorOpts().DisablePragmaDebugCrash = true;
 
-  if (Inputs.Opts.BuildRecoveryAST)
-CI->getLangOpt

[llvm-branch-commits] [clang-tools-extra] 2ab5fd2 - [clangd] Retire some flags for uncontroversial, stable features.

2021-01-20 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-20T11:47:12+01:00
New Revision: 2ab5fd2c8567ac89d7e7639563babdfc78dbcf78

URL: 
https://github.com/llvm/llvm-project/commit/2ab5fd2c8567ac89d7e7639563babdfc78dbcf78
DIFF: 
https://github.com/llvm/llvm-project/commit/2ab5fd2c8567ac89d7e7639563babdfc78dbcf78.diff

LOG: [clangd] Retire some flags for uncontroversial, stable features.

And mark a couple to be retired afther the next release branch.

Differential Revision: https://reviews.llvm.org/D94727

Added: 


Modified: 
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/Compiler.h
clang-tools-extra/clangd/ParsedAST.cpp
clang-tools-extra/clangd/tool/ClangdMain.cpp
clang-tools-extra/clangd/unittests/TestTU.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 123d755f267e..32e08e688f44 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -146,7 +146,6 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase 
&CDB,
  Opts.CollectMainFileRefs)
  : nullptr),
   ClangTidyProvider(Opts.ClangTidyProvider),
-  SuggestMissingIncludes(Opts.SuggestMissingIncludes),
   WorkspaceRoot(Opts.WorkspaceRoot),
   // Pass a callback into `WorkScheduler` to extract symbols from a newly
   // parsed file and rebuild the file index synchronously each time an AST
@@ -201,7 +200,6 @@ void ClangdServer::addDocument(PathRef File, 
llvm::StringRef Contents,
llvm::StringRef Version,
WantDiagnostics WantDiags, bool ForceRebuild) {
   ParseOptions Opts;
-  Opts.SuggestMissingIncludes = SuggestMissingIncludes;
 
   // Compile command is set asynchronously during update, as it can be slow.
   ParseInputs Inputs;

diff  --git a/clang-tools-extra/clangd/ClangdServer.h 
b/clang-tools-extra/clangd/ClangdServer.h
index 832f8b04a11d..926de39b507a 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -136,8 +136,6 @@ class ClangdServer {
 /*RebuildRatio=*/1,
 };
 
-bool SuggestMissingIncludes = false;
-
 /// Clangd will execute compiler drivers matching one of these globs to
 /// fetch system include path.
 std::vector QueryDriverGlobs;
@@ -376,10 +374,6 @@ class ClangdServer {
   // When set, provides clang-tidy options for a specific file.
   TidyProviderRef ClangTidyProvider;
 
-  // If this is true, suggest include insertion fixes for diagnostic errors 
that
-  // can be caused by missing includes (e.g. member access in incomplete type).
-  bool SuggestMissingIncludes = false;
-
   // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
   llvm::StringMap>
   CachedCompletionFuzzyFindRequestByFile;

diff  --git a/clang-tools-extra/clangd/Compiler.h 
b/clang-tools-extra/clangd/Compiler.h
index c46fb764d317..13fd4da33e3c 100644
--- a/clang-tools-extra/clangd/Compiler.h
+++ b/clang-tools-extra/clangd/Compiler.h
@@ -37,7 +37,7 @@ class IgnoreDiagnostics : public DiagnosticConsumer {
 
 // Options to run clang e.g. when parsing AST.
 struct ParseOptions {
-  bool SuggestMissingIncludes = false;
+  // (empty at present, formerly controlled recovery AST, include-fixer etc)
 };
 
 /// Information required to run clang, e.g. to parse AST or do code completion.

diff  --git a/clang-tools-extra/clangd/ParsedAST.cpp 
b/clang-tools-extra/clangd/ParsedAST.cpp
index 228db29b2be3..a8c4eea54540 100644
--- a/clang-tools-extra/clangd/ParsedAST.cpp
+++ b/clang-tools-extra/clangd/ParsedAST.cpp
@@ -351,8 +351,7 @@ ParsedAST::build(llvm::StringRef Filename, const 
ParseInputs &Inputs,
   // (e.g. incomplete type) and attach include insertion fixes to diagnostics.
   llvm::Optional FixIncludes;
   auto BuildDir = VFS->getCurrentWorkingDirectory();
-  if (Inputs.Opts.SuggestMissingIncludes && Inputs.Index &&
-  !BuildDir.getError()) {
+  if (Inputs.Index && !BuildDir.getError()) {
 auto Style = getFormatStyleForFile(Filename, Inputs.Contents, *Inputs.TFS);
 auto Inserter = std::make_shared(
 Filename, Inputs.Contents, Style, BuildDir.get(),

diff  --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp 
b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 5cbf8aa0df90..fe69079bfe67 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -80,8 +80,21 @@ OptionCategory CompileCommands("clangd compilation flags 
options");
 OptionCategory Features("clangd feature options");
 OptionCategory Misc("clangd miscellaneous options");
 OptionCategory Protocol("clangd protocol and logging options");
+OptionCategory Retired("clangd flags no longer in use");
 const OptionCategory *ClangdCategories[] = {&Features, &Proto

[llvm-branch-commits] [clang-tools-extra] 60cd75a - [clangd] Inject context provider rather than config into ClangdServer. NFC

2021-01-22 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-22T14:34:30+01:00
New Revision: 60cd75a098d4f18d9c8903ddcb466b4e7deb0580

URL: 
https://github.com/llvm/llvm-project/commit/60cd75a098d4f18d9c8903ddcb466b4e7deb0580
DIFF: 
https://github.com/llvm/llvm-project/commit/60cd75a098d4f18d9c8903ddcb466b4e7deb0580.diff

LOG: [clangd] Inject context provider rather than config into ClangdServer. NFC

This is a step towards allowing CDB behavior to being configurable.

Previously ClangdServer itself created the configs and installed them into
contexts. This was natural as it knows how to deal with resulting diagnostics.

However this prevents config being used in CDB, which must be created before
ClangdServer. So we extract the context provider (config loader) as a separate
object, which publishes diagnostics to a ClangdServer::Callbacks itself.

Now initialization looks like:
 - First create the config::Provider
 - Then create the ClangdLSPServer, passing config provider
 - Next, create the context provider, passing config provider + diagnostic 
callbacks
 - now create the CDB, passing context provider
 - finally create ClangdServer, passing CDB, context provider, and diagnostic 
callbacks

Differential Revision: https://reviews.llvm.org/D95087

Added: 


Modified: 
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdLSPServer.h
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/unittests/ClangdTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp 
b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 4e5d9f8bf0fa..24d3a3509ca8 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -1469,6 +1469,12 @@ ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
   MsgHandler(new MessageHandler(*this)), TFS(TFS),
   SupportedSymbolKinds(defaultSymbolKinds()),
   SupportedCompletionItemKinds(defaultCompletionItemKinds()), Opts(Opts) {
+  if (Opts.ConfigProvider) {
+assert(!Opts.ContextProvider &&
+   "Only one of ConfigProvider and ContextProvider allowed!");
+this->Opts.ContextProvider = ClangdServer::createConfiguredContextProvider(
+Opts.ConfigProvider, this);
+  }
 
   // clang-format off
   MsgHandler->bind("initialize", &ClangdLSPServer::onInitialize);

diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.h 
b/clang-tools-extra/clangd/ClangdLSPServer.h
index a41bc5666af3..3a46bd7b1bea 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -41,6 +41,8 @@ class SymbolIndex;
 class ClangdLSPServer : private ClangdServer::Callbacks {
 public:
   struct Options : ClangdServer::Options {
+/// Supplies configuration (overrides ClangdServer::ContextProvider).
+config::Provider *ConfigProvider = nullptr;
 /// Look for compilation databases, rather than using compile commands
 /// set via LSP (extensions) only.
 bool UseDirBasedCDB = true;

diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 32e08e688f44..4f9ea0499077 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -133,14 +133,14 @@ ClangdServer::Options::operator TUScheduler::Options() 
const {
   Opts.StorePreamblesInMemory = StorePreamblesInMemory;
   Opts.UpdateDebounce = UpdateDebounce;
   Opts.AsyncPreambleBuilds = AsyncPreambleBuilds;
+  Opts.ContextProvider = ContextProvider;
   return Opts;
 }
 
 ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
const ThreadsafeFS &TFS, const Options &Opts,
Callbacks *Callbacks)
-: ConfigProvider(Opts.ConfigProvider), CDB(CDB), TFS(TFS),
-  ServerCallbacks(Callbacks),
+: CDB(CDB), TFS(TFS),
   DynamicIdx(Opts.BuildDynamicSymbolIndex
  ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex,
  Opts.CollectMainFileRefs)
@@ -153,14 +153,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase 
&CDB,
   // FIXME(ioeric): this can be slow and we may be able to index on less
   // critical paths.
   WorkScheduler(
-  CDB,
-  [&, this] {
-TUScheduler::Options O(Opts);
-O.ContextProvider = [this](PathRef P) {
-  return createProcessingContext(P);
-};
-return O;
-  }(),
+  CDB, TUScheduler::Options(Opts),
   std::make_unique(
   DynamicIdx.get(), Callbacks, Opts.TheiaSemanticHighlighting)) {
   // Adds an index to the stack, at higher priority than existing indexes.
@@ -181,9 +174,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase 
&CDB,
   if (Callbacks)
 Callbacks->onBackground

[llvm-branch-commits] [clang-tools-extra] 2f8d1e9 - [clangd] When querying drivers by binary, look in PATH too

2021-01-05 Thread Sam McCall via llvm-branch-commits

Author: Giulio Girardi
Date: 2021-01-05T12:54:07+01:00
New Revision: 2f8d1e9eb27e111eb6dfd242d88dd7c98005fb5c

URL: 
https://github.com/llvm/llvm-project/commit/2f8d1e9eb27e111eb6dfd242d88dd7c98005fb5c
DIFF: 
https://github.com/llvm/llvm-project/commit/2f8d1e9eb27e111eb6dfd242d88dd7c98005fb5c.diff

LOG: [clangd] When querying drivers by binary, look in PATH too

Sometimes compile_commands.json databases are created without an
absolute path for the driver in the command field. By default the driver
name is appended to the current directory, however if no driver is found
in that location assume it was in the default PATH and try finding it
there

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D93600

Added: 


Modified: 
clang-tools-extra/clangd/QueryDriverDatabase.cpp
clang-tools-extra/clangd/test/system-include-extractor.test

Removed: 




diff  --git a/clang-tools-extra/clangd/QueryDriverDatabase.cpp 
b/clang-tools-extra/clangd/QueryDriverDatabase.cpp
index 797771ce144e..f1a4b5fcbfc8 100644
--- a/clang-tools-extra/clangd/QueryDriverDatabase.cpp
+++ b/clang-tools-extra/clangd/QueryDriverDatabase.cpp
@@ -136,10 +136,26 @@ llvm::Optional 
parseDriverOutput(llvm::StringRef Output) {
 }
 
 llvm::Optional
-extractSystemIncludesAndTarget(PathRef Driver, llvm::StringRef Lang,
+extractSystemIncludesAndTarget(llvm::SmallString<128> Driver,
+   llvm::StringRef Lang,
llvm::ArrayRef CommandLine,
const llvm::Regex &QueryDriverRegex) {
   trace::Span Tracer("Extract system includes and target");
+
+  if (!llvm::sys::path::is_absolute(Driver)) {
+assert(llvm::none_of(
+Driver, [](char C) { return llvm::sys::path::is_separator(C); }));
+auto DriverProgram = llvm::sys::findProgramByName(Driver);
+if (DriverProgram) {
+  vlog("System include extraction: driver {0} expanded to {1}", Driver,
+   *DriverProgram);
+  Driver = *DriverProgram;
+} else {
+  elog("System include extraction: driver {0} not found in PATH", Driver);
+  return llvm::None;
+}
+  }
+
   SPAN_ATTACH(Tracer, "driver", Driver);
   SPAN_ATTACH(Tracer, "lang", Lang);
 
@@ -332,7 +348,11 @@ class QueryDriverDatabase : public 
GlobalCompilationDatabase {
 }
 
 llvm::SmallString<128> Driver(Cmd->CommandLine.front());
-llvm::sys::fs::make_absolute(Cmd->Directory, Driver);
+if (llvm::any_of(Driver,
+   [](char C) { return llvm::sys::path::is_separator(C); 
}))
+  // Driver is a not a single executable name but instead a path (either
+  // relative or absolute).
+  llvm::sys::fs::make_absolute(Cmd->Directory, Driver);
 
 if (auto Info =
 QueriedDrivers.get(/*Key=*/(Driver + ":" + Lang).str(), [&] {

diff  --git a/clang-tools-extra/clangd/test/system-include-extractor.test 
b/clang-tools-extra/clangd/test/system-include-extractor.test
index 59989be6ca6c..c861a2346470 100644
--- a/clang-tools-extra/clangd/test/system-include-extractor.test
+++ b/clang-tools-extra/clangd/test/system-include-extractor.test
@@ -3,21 +3,24 @@
 # The mock driver below is a shell script:
 # REQUIRES: shell
 
+# Create a bin directory to store the mock-driver and add it to the path
+# RUN: mkdir -p %t.dir/bin
+# RUN: export PATH=%t.dir/bin:$PATH
 # Generate a mock-driver that will print %temp_dir%/my/dir and
 # %temp_dir%/my/dir2 as include search paths.
-# RUN: echo '#!/bin/sh' >> %t.dir/my_driver.sh
-# RUN: echo '[ "$0" = "%t.dir/my_driver.sh" ] || exit' >> %t.dir/my_driver.sh
-# RUN: echo 'args="$*"' >> %t.dir/my_driver.sh
-# RUN: echo '[ -z "${args##*"-nostdinc"*}" ] || exit' >> %t.dir/my_driver.sh
-# RUN: echo '[ -z "${args##*"-isysroot=/isysroot"*}" ] || exit' >> 
%t.dir/my_driver.sh
-# RUN: echo 'echo " $* " | grep " --sysroot /my/sysroot/path " || exit' >> 
%t.dir/my_driver.sh
-# RUN: echo 'echo line to ignore >&2' >> %t.dir/my_driver.sh
-# RUN: echo 'printf "Target: arm-linux-gnueabihf\r\n" >&2' >> 
%t.dir/my_driver.sh
-# RUN: echo 'printf "#include <...> search starts here:\r\n" >&2' >> 
%t.dir/my_driver.sh
-# RUN: echo 'echo %t.dir/my/dir/ >&2' >> %t.dir/my_driver.sh
-# RUN: echo 'echo %t.dir/my/dir2/ >&2' >> %t.dir/my_driver.sh
-# RUN: echo 'printf "End of search list.\r\n" >&2' >> %t.dir/my_driver.sh
-# RUN: chmod +x %t.dir/my_driver.sh
+# RUN: echo '#!/bin/sh' >> %t.dir/bin/my_driver.sh
+# RUN: echo '[ "$0" = "%t.dir/bin/my_driver.sh" ] || exit' >> 
%t.dir/bin/my_driver.sh
+# RUN: echo 'args="$*"' >> %t.dir/bin/my_driver.sh
+# RUN: echo '[ -z "${args##*"-nostdinc"*}" ] || exit' >> 
%t.dir/bin/my_driver.sh
+# RUN: echo '[ -z "${args##*"-isysroot=/isysroot"*}" ] || exit' >> 
%t.dir/bin/my_driver.sh
+# RUN: echo 'echo " $* " | grep " --sysroot /my/sysroot/path " || exit' >> 
%t.dir/bin/my_driver.sh
+# RUN: echo 'echo line to ignore >&2' >> %t.dir/bin/my_d

[llvm-branch-commits] [clang-tools-extra] 213329d - [clangd] Add server capability advertising hot-reloading of CDBs.

2021-01-07 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2021-01-07T13:39:21+01:00
New Revision: 213329d7c64f9710f23a78596255509b147b37c6

URL: 
https://github.com/llvm/llvm-project/commit/213329d7c64f9710f23a78596255509b147b37c6
DIFF: 
https://github.com/llvm/llvm-project/commit/213329d7c64f9710f23a78596255509b147b37c6.diff

LOG: [clangd] Add server capability advertising hot-reloading of CDBs.

Currently some clients watch for CDB changes and restart clangd, now that we
can reload compile_commands.json ourselves this is counterproductive.
The capability allows this behavior to be phased out.

This is going to be a mild regression, as we do not actually watch for files on
disk and so new diagnostics need to wait until a rebuild is requested e.g. due
to file change (and the internal caches have expired).
However this is still a better tradeoff (and if it's important, we can request
the client to watch files for us in the future).

Differential Revision: https://reviews.llvm.org/D94222

Added: 


Modified: 
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/test/initialize-params.test

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp 
b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index c606ccae4fdc..4e5d9f8bf0fa 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -620,7 +620,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams 
&Params,
 {"documentSymbolProvider", true},
 {"workspaceSymbolProvider", true},
 {"referencesProvider", true},
-{"astProvider", true},
+{"astProvider", true}, // clangd extension
 {"executeCommandProvider",
  llvm::json::Object{
  {"commands",
@@ -628,7 +628,9 @@ void ClangdLSPServer::onInitialize(const InitializeParams 
&Params,
ExecuteCommandParams::CLANGD_APPLY_TWEAK}},
  }},
 {"typeHierarchyProvider", true},
-{"memoryUsageProvider", true}, // clangd extension.
+{"memoryUsageProvider", true}, // clangd extension
+{"compilationDatabase",// clangd extension
+ llvm::json::Object{{"automaticReload", true}}},
 {"callHierarchyProvider", true},
 ;
   if (Opts.Encoding)

diff  --git a/clang-tools-extra/clangd/test/initialize-params.test 
b/clang-tools-extra/clangd/test/initialize-params.test
index e4f4bf18dee4..907ab0ade420 100644
--- a/clang-tools-extra/clangd/test/initialize-params.test
+++ b/clang-tools-extra/clangd/test/initialize-params.test
@@ -8,6 +8,9 @@
 # CHECK-NEXT:  "astProvider": true,
 # CHECK-NEXT:  "callHierarchyProvider": true,
 # CHECK-NEXT:  "codeActionProvider": true,
+# CHECK-NEXT:  "compilationDatabase": {
+# CHECK-NEXT:"automaticReload": true
+# CHECK-NEXT:  },
 # CHECK-NEXT:  "completionProvider": {
 # CHECK-NEXT:"allCommitCharacters": [
 # CHECK-NEXT:  " ",



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] 02129ea - [Syntax] avoid using c++17 features on 15.x branch

2022-10-10 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2022-10-10T17:08:10+02:00
New Revision: 02129eab7d58362ad5d187c73aff255710578e75

URL: 
https://github.com/llvm/llvm-project/commit/02129eab7d58362ad5d187c73aff255710578e75
DIFF: 
https://github.com/llvm/llvm-project/commit/02129eab7d58362ad5d187c73aff255710578e75.diff

LOG: [Syntax] avoid using c++17 features on 15.x branch

Added: 


Modified: 
clang/lib/Tooling/Syntax/Tokens.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Syntax/Tokens.cpp 
b/clang/lib/Tooling/Syntax/Tokens.cpp
index 9a30e3692ee54..1fa73c667b7f2 100644
--- a/clang/lib/Tooling/Syntax/Tokens.cpp
+++ b/clang/lib/Tooling/Syntax/Tokens.cpp
@@ -460,8 +460,10 @@ 
TokenBuffer::spelledForExpanded(llvm::ArrayRef Expanded) const {
 return llvm::None;
   const syntax::Token *First = &Expanded.front();
   const syntax::Token *Last = &Expanded.back();
-  auto [FirstSpelled, FirstMapping] = spelledForExpandedToken(First);
-  auto [LastSpelled, LastMapping] = spelledForExpandedToken(Last);
+  const syntax::Token *FirstSpelled, *LastSpelled;
+  const TokenBuffer::Mapping *FirstMapping, *LastMapping;
+  std::tie(FirstSpelled, FirstMapping) = spelledForExpandedToken(First);
+  std::tie(LastSpelled, LastMapping) = spelledForExpandedToken(Last);
 
   FileID FID = SourceMgr->getFileID(FirstSpelled->location());
   // FIXME: Handle multi-file changes by trying to map onto a common root.



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 9c328e7 - [clangd] Add hover info for `this` expr

2020-12-15 Thread Sam McCall via llvm-branch-commits

Author: xndcn
Date: 2020-12-15T09:47:29+01:00
New Revision: 9c328e7afafd15795fed54e3b0c1c5bd4fa97dfa

URL: 
https://github.com/llvm/llvm-project/commit/9c328e7afafd15795fed54e3b0c1c5bd4fa97dfa
DIFF: 
https://github.com/llvm/llvm-project/commit/9c328e7afafd15795fed54e3b0c1c5bd4fa97dfa.diff

LOG: [clangd] Add hover info for `this` expr

How about add hover information for `this` expr?
It seems useful to show related information about the class for `this` expr 
sometimes.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D92041

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index d599ccb557c28..e461c7c433645 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -552,7 +552,8 @@ HoverInfo getHoverContents(const NamedDecl *D, const 
SymbolIndex *Index) {
 
 /// Generate a \p Hover object given the type \p T.
 HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx,
-   const SymbolIndex *Index) {
+   const SymbolIndex *Index,
+   bool SuppressScope = false) {
   HoverInfo HI;
 
   if (const auto *D = T->getAsTagDecl()) {
@@ -566,6 +567,7 @@ HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx,
 // Builtin types
 auto Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
 Policy.SuppressTagKeyword = true;
+Policy.SuppressScope = SuppressScope;
 HI.Name = T.getAsString(Policy);
   }
   return HI;
@@ -628,15 +630,29 @@ llvm::StringLiteral getNameForExpr(const Expr *E) {
   return llvm::StringLiteral("expression");
 }
 
-// Generates hover info for evaluatable expressions.
+// Generates hover info for `this` and evaluatable expressions.
 // FIXME: Support hover for literals (esp user-defined)
-llvm::Optional getHoverContents(const Expr *E, ParsedAST &AST) {
+llvm::Optional getHoverContents(const Expr *E, ParsedAST &AST,
+   const SymbolIndex *Index) {
   // There's not much value in hovering over "42" and getting a hover card
   // saying "42 is an int", similar for other literals.
   if (isLiteral(E))
 return llvm::None;
 
   HoverInfo HI;
+  // For `this` expr we currently generate hover with pointee type.
+  if (const CXXThisExpr *CTE = dyn_cast(E)) {
+QualType OriginThisType = CTE->getType()->getPointeeType();
+QualType ClassType = declaredType(OriginThisType->getAsTagDecl());
+// For partial specialization class, origin `this` pointee type will be
+// parsed as `InjectedClassNameType`, which will ouput template arguments
+// like "type-parameter-0-0". So we retrieve user written class type in 
this
+// case.
+QualType PrettyThisType = AST.getASTContext().getPointerType(
+QualType(ClassType.getTypePtr(), OriginThisType.getCVRQualifiers()));
+return getHoverContents(PrettyThisType, AST.getASTContext(), Index,
+/*SuppressScope=*/true);
+  }
   // For expressions we currently print the type and the value, iff it is
   // evaluatable.
   if (auto Val = printExprValue(E, AST.getASTContext())) {
@@ -861,7 +877,7 @@ llvm::Optional getHover(ParsedAST &AST, Position 
Pos,
   HI->Value = printExprValue(N, AST.getASTContext());
 maybeAddCalleeArgInfo(N, *HI, AST.getASTContext().getPrintingPolicy());
   } else if (const Expr *E = N->ASTNode.get()) {
-HI = getHoverContents(E, AST);
+HI = getHoverContents(E, AST, Index);
   }
   // FIXME: support hovers for other nodes?
   //  - built-in types

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp 
b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index fdebf0da67103..bac0e525664b2 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -2019,6 +2019,56 @@ TEST(Hover, All) {
 HI.NamespaceScope = "";
 HI.Definition = "@interface MYObject\n@end";
   }},
+  {
+  R"cpp(// this expr
+  // comment
+  namespace ns {
+class Foo {
+  Foo* bar() {
+return [[t^his]];
+  }
+};
+  }
+  )cpp",
+  [](HoverInfo &HI) { HI.Name = "Foo *"; }},
+  {
+  R"cpp(// this expr for template class
+  namespace ns {
+template 
+class Foo {
+  Foo* bar() const {
+return [[t^his]];
+  }
+};
+  }
+  )cpp",
+  [](HoverInfo &HI) { HI.Name = "const Foo *"; }},
+  {
+  R"cpp(// this expr for specialization class
+  namespace ns {
+template  class Foo {};
+ 

[llvm-branch-commits] [clang-tools-extra] 965d71c - [clangd] Avoid traversing C:\ -> C: when looking for CDBs

2020-12-15 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-15T13:59:00+01:00
New Revision: 965d71c69acce658e9e3de00b25a351b00937820

URL: 
https://github.com/llvm/llvm-project/commit/965d71c69acce658e9e3de00b25a351b00937820
DIFF: 
https://github.com/llvm/llvm-project/commit/965d71c69acce658e9e3de00b25a351b00937820.diff

LOG: [clangd] Avoid traversing C:\ -> C: when looking for CDBs

Boost in its infinite wisdom considers C: a parent of C:\, and we've
inherited that. This breaks the assumption that after canonicalizing a
path, the path parents are the directory's parents.

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index 23e8c9fe716d..20139c12abed 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -29,13 +29,27 @@ namespace clang {
 namespace clangd {
 namespace {
 
+// Variant of parent_path that operates only on absolute paths.
+PathRef absoluteParent(PathRef Path) {
+  assert(llvm::sys::path::is_absolute(Path));
+#if defined(_WIN32)
+  // llvm::sys says "C:\" is absolute, and its parent is "C:" which is 
relative.
+  // This unhelpful behavior seems to have been inherited from boost.
+  if (llvm::sys::path::relative_path(Path)).empty(); {
+return PathRef();
+  }
+#endif
+  PathRef Result = llvm::sys::path::parent_path(Path);
+  assert(Result.empty() || llvm::sys::path::is_absolute(Result));
+  return Result;
+}
+
 // Runs the given action on all parent directories of filename, starting from
 // deepest directory and going up to root. Stops whenever action succeeds.
 void actOnAllParentDirectories(PathRef FileName,
llvm::function_ref Action) {
-  for (auto Path = llvm::sys::path::parent_path(FileName);
-   !Path.empty() && !Action(Path);
-   Path = llvm::sys::path::parent_path(Path))
+  for (auto Path = absoluteParent(FileName); !Path.empty() && !Action(Path);
+   Path = absoluteParent(Path))
 ;
 }
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 92dd077 - Reland [clangd] Extract per-dir CDB cache to its own threadsafe class. NFC

2020-12-15 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-15T14:00:03+01:00
New Revision: 92dd077af1ff89929f5502c6c887358f51d5afc1

URL: 
https://github.com/llvm/llvm-project/commit/92dd077af1ff89929f5502c6c887358f51d5afc1
DIFF: 
https://github.com/llvm/llvm-project/commit/92dd077af1ff89929f5502c6c887358f51d5afc1.diff

LOG: Reland [clangd] Extract per-dir CDB cache to its own threadsafe class. NFC

This reverts commit 4d956af594c5adc9d566d1846d86dd89c70c9c0b.

Assertion failures on windows fixed by
965d71c69acce658e9e3de00b25a351b00937820

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index 20139c12abed..bad9c359798e 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -16,11 +16,13 @@
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
+#include 
 #include 
 #include 
 #include 
@@ -72,10 +74,117 @@ GlobalCompilationDatabase::getFallbackCommand(PathRef 
File) const {
   return Cmd;
 }
 
+// Loads and caches the CDB from a single directory.
+//
+// This class is threadsafe, which is to say we have independent locks for each
+// directory we're searching for a CDB.
+// Loading is deferred until first access.
+//
+// The DirectoryBasedCDB keeps a map from path => DirectoryCache.
+// Typical usage is to:
+//  - 1) determine all the paths that might be searched
+//  - 2) acquire the map lock and get-or-create all the DirectoryCache entries
+//  - 3) release the map lock and query the caches as desired
+//
+// FIXME: this should revalidate the cache sometimes
+// FIXME: IO should go through a VFS
+class DirectoryBasedGlobalCompilationDatabase::DirectoryCache {
+  // Absolute canonical path that we're the cache for. (Not case-folded).
+  const std::string Path;
+
+  // True if we've looked for a CDB here and found none.
+  // (This makes it possible for get() to return without taking a lock)
+  // FIXME: this should have an expiry time instead of lasting forever.
+  std::atomic FinalizedNoCDB = {false};
+
+  // Guards following cache state.
+  std::mutex Mu;
+  // Has cache been filled from disk? FIXME: this should be an expiry time.
+  bool CachePopulated = false;
+  // Whether a new CDB has been loaded but not broadcast yet.
+  bool NeedsBroadcast = false;
+  // Last loaded CDB, meaningful if CachePopulated is set.
+  // shared_ptr so we can overwrite this when callers are still using the CDB.
+  std::shared_ptr CDB;
+
+public:
+  DirectoryCache(llvm::StringRef Path) : Path(Path) {
+assert(llvm::sys::path::is_absolute(Path));
+  }
+
+  // Get the CDB associated with this directory.
+  // ShouldBroadcast:
+  //  - as input, signals whether the caller is willing to broadcast a
+  //newly-discovered CDB. (e.g. to trigger background indexing)
+  //  - as output, signals whether the caller should do so.
+  // (If a new CDB is discovered and ShouldBroadcast is false, we mark the
+  // CDB as needing broadcast, and broadcast it next time we can).
+  std::shared_ptr
+  get(bool &ShouldBroadcast) {
+// Fast path for common case without taking lock.
+if (FinalizedNoCDB.load()) {
+  ShouldBroadcast = false;
+  return nullptr;
+}
+std::lock_guard Lock(Mu);
+auto RequestBroadcast = llvm::make_scope_exit([&, OldCDB(CDB.get())] {
+  // If we loaded a new CDB, it should be broadcast at some point.
+  if (CDB != nullptr && CDB.get() != OldCDB)
+NeedsBroadcast = true;
+  else if (CDB == nullptr) // nothing to broadcast anymore!
+NeedsBroadcast = false;
+  // If we have something to broadcast, then do so iff allowed.
+  if (!ShouldBroadcast)
+return;
+  ShouldBroadcast = NeedsBroadcast;
+  NeedsBroadcast = false;
+});
+
+// For now, we never actually attempt to revalidate a populated cache.
+if (CachePopulated)
+  return CDB;
+assert(CDB == nullptr);
+
+load();
+CachePopulated = true;
+
+if (!CDB)
+  FinalizedNoCDB.store(true);
+return CDB;
+  }
+
+  llvm::StringRef path() const { return Path; }
+
+private:
+  // Updates `CDB` from disk state.
+  void load() {
+std::string Error; // ignored, because it's often "didn't find anything".
+CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
+if (!CDB) {
+  // Fallback: check for $src/build, the conventional CMake build root.
+  // Probe existence first to avoid each plugin doing IO if it doesn't
+  /

[llvm-branch-commits] [clang-tools-extra] 5186eda - [clangd] Oops, fix code in #ifdef WIN32

2020-12-15 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-15T14:17:54+01:00
New Revision: 5186eda3269333b2fb38800e9ded2a27ae87f99b

URL: 
https://github.com/llvm/llvm-project/commit/5186eda3269333b2fb38800e9ded2a27ae87f99b
DIFF: 
https://github.com/llvm/llvm-project/commit/5186eda3269333b2fb38800e9ded2a27ae87f99b.diff

LOG: [clangd] Oops, fix code in #ifdef WIN32

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index bad9c359798e..add0eec4a2c8 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -37,7 +37,7 @@ PathRef absoluteParent(PathRef Path) {
 #if defined(_WIN32)
   // llvm::sys says "C:\" is absolute, and its parent is "C:" which is 
relative.
   // This unhelpful behavior seems to have been inherited from boost.
-  if (llvm::sys::path::relative_path(Path)).empty(); {
+  if (llvm::sys::path::relative_path(Path).empty()) {
 return PathRef();
   }
 #endif



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] bda7d0a - [clangd] Improve goToDefinition on auto and dectype

2020-12-15 Thread Sam McCall via llvm-branch-commits

Author: Quentin Chateau
Date: 2020-12-15T16:32:22+01:00
New Revision: bda7d0af970718c243d93b22a8449c20156e574f

URL: 
https://github.com/llvm/llvm-project/commit/bda7d0af970718c243d93b22a8449c20156e574f
DIFF: 
https://github.com/llvm/llvm-project/commit/bda7d0af970718c243d93b22a8449c20156e574f.diff

LOG: [clangd] Improve goToDefinition on auto and dectype

locateSymbolAt (used in goToDeclaration) follows the
deduced type instead of failing to locate the declaration.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D92977

Added: 


Modified: 
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/ASTTests.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/XRefs.cpp 
b/clang-tools-extra/clangd/XRefs.cpp
index ac4543026a9f..c7ec401c6479 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -463,6 +463,42 @@ locateASTReferent(SourceLocation CurLoc, const 
syntax::Token *TouchedIdentifier,
   return Result;
 }
 
+std::vector locateSymbolForType(const ParsedAST &AST,
+   const QualType &Type) {
+  const auto &SM = AST.getSourceManager();
+  auto MainFilePath =
+  getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
+  if (!MainFilePath) {
+elog("Failed to get a path for the main file, so no symbol.");
+return {};
+  }
+
+  auto Decls = targetDecl(DynTypedNode::create(Type.getNonReferenceType()),
+  DeclRelation::TemplatePattern | DeclRelation::Alias);
+  if (Decls.empty())
+return {};
+
+  std::vector Results;
+  const auto &ASTContext = AST.getASTContext();
+
+  for (const NamedDecl *D : Decls) {
+D = getPreferredDecl(D);
+
+auto Loc = makeLocation(ASTContext, nameLocation(*D, SM), *MainFilePath);
+if (!Loc)
+  continue;
+
+Results.emplace_back();
+Results.back().Name = printName(ASTContext, *D);
+Results.back().PreferredDeclaration = *Loc;
+if (const NamedDecl *Def = getDefinition(D))
+  Results.back().Definition =
+  makeLocation(ASTContext, nameLocation(*Def, SM), *MainFilePath);
+  }
+
+  return Results;
+}
+
 bool tokenSpelledAt(SourceLocation SpellingLoc, const syntax::TokenBuffer &TB) 
{
   auto ExpandedTokens = TB.expandedTokens(
   TB.sourceManager().getMacroArgExpandedLocation(SpellingLoc));
@@ -707,15 +743,31 @@ std::vector locateSymbolAt(ParsedAST &AST, 
Position Pos,
 return {};
   }
 
-  const syntax::Token *TouchedIdentifier =
-  syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens());
-  if (TouchedIdentifier)
-if (auto Macro =
-locateMacroReferent(*TouchedIdentifier, AST, *MainFilePath))
-  // Don't look at the AST or index if we have a macro result.
-  // (We'd just return declarations referenced from the macro's
-  // expansion.)
-  return {*std::move(Macro)};
+  const syntax::Token *TouchedIdentifier = nullptr;
+  auto TokensTouchingCursor =
+  syntax::spelledTokensTouching(*CurLoc, AST.getTokens());
+  for (const syntax::Token &Tok : TokensTouchingCursor) {
+if (Tok.kind() == tok::identifier) {
+  if (auto Macro = locateMacroReferent(Tok, AST, *MainFilePath))
+// Don't look at the AST or index if we have a macro result.
+// (We'd just return declarations referenced from the macro's
+// expansion.)
+return {*std::move(Macro)};
+
+  TouchedIdentifier = &Tok;
+  break;
+}
+
+if (Tok.kind() == tok::kw_auto || Tok.kind() == tok::kw_decltype) {
+  // go-to-definition on auto should find the definition of the deduced
+  // type, if possible
+  if (auto Deduced = getDeducedType(AST.getASTContext(), Tok.location())) {
+auto LocSym = locateSymbolForType(AST, *Deduced);
+if (!LocSym.empty())
+  return LocSym;
+  }
+}
+  }
 
   ASTNodeKind NodeKind;
   auto ASTResults = locateASTReferent(*CurLoc, TouchedIdentifier, AST,

diff  --git a/clang-tools-extra/clangd/unittests/ASTTests.cpp 
b/clang-tools-extra/clangd/unittests/ASTTests.cpp
index 21f70dcc3168..4c52c72d703c 100644
--- a/clang-tools-extra/clangd/unittests/ASTTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ASTTests.cpp
@@ -26,23 +26,168 @@ namespace clang {
 namespace clangd {
 namespace {
 
-TEST(GetDeducedType, KwAutoExpansion) {
+TEST(GetDeducedType, KwAutoKwDecltypeExpansion) {
   struct Test {
 StringRef AnnotatedCode;
 const char *DeducedType;
   } Tests[] = {
   {"^auto i = 0;", "int"},
   {"^auto f(){ return 1;};", "int"},
+  {
+  R"cpp( // auto on struct in a namespace
+  namespace ns1 { struct S {}; }
+  ^auto v = ns1::S{};
+  )cpp",
+  "struct ns1::S",
+  },
+  {
+  R"cpp( // decltype on struct
+  namespace ns1 { struct S 

[llvm-branch-commits] [clang-tools-extra] 894c476 - [clangd] Add llvm:: qualifier to work around GCC bug. NFC

2020-12-17 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-17T12:51:12+01:00
New Revision: 894c4761c67ac850e156a26aa427035a811d7aed

URL: 
https://github.com/llvm/llvm-project/commit/894c4761c67ac850e156a26aa427035a811d7aed
DIFF: 
https://github.com/llvm/llvm-project/commit/894c4761c67ac850e156a26aa427035a811d7aed.diff

LOG: [clangd] Add llvm:: qualifier to work around GCC bug. NFC

Some old GCC versions seem to miss the default template parameter when
using the clang/Basic/LLVM.h forward declarations of SmallVector.

See D92788

Added: 


Modified: 
clang-tools-extra/clangd/Headers.h

Removed: 




diff  --git a/clang-tools-extra/clangd/Headers.h 
b/clang-tools-extra/clangd/Headers.h
index d86a4788f0a6..fd9db5562813 100644
--- a/clang-tools-extra/clangd/Headers.h
+++ b/clang-tools-extra/clangd/Headers.h
@@ -136,7 +136,7 @@ class IncludeStructure {
   unsigned fileIndex(llvm::StringRef Name);
   llvm::StringMap NameToIndex; // Values are file indexes.
   // Maps a file's index to that of the files it includes.
-  llvm::DenseMap> IncludeChildren;
+  llvm::DenseMap> IncludeChildren;
 };
 
 /// Returns a PPCallback that visits all inclusions in the main file.



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 9899319 - [clangd] Add hot-reload of compile_commands.json and compile_flags.txt

2020-12-18 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-18T11:16:46+01:00
New Revision: 98993193e9037345ad13720a62974064a5f3d953

URL: 
https://github.com/llvm/llvm-project/commit/98993193e9037345ad13720a62974064a5f3d953
DIFF: 
https://github.com/llvm/llvm-project/commit/98993193e9037345ad13720a62974064a5f3d953.diff

LOG: [clangd] Add hot-reload of compile_commands.json and compile_flags.txt

When querying the CDB, we stat the underlying file to check it hasn't changed.
We don't do this every time, but only if we didn't check within 5 seconds.

This behavior only exists for compile_commands.json and compile_flags.txt.
The CDB plugin system doesn't expose enough information to handle others.

Slight behavior change: we now only look for `build/compile_commands.json`
rather than trying every CDB strategy under `build` subdirectories.

Differential Revision: https://reviews.llvm.org/D92663

Added: 


Modified: 
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h
clang-tools-extra/clangd/tool/Check.cpp
clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp 
b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 66dee68ec474..b32c9e13973b 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -496,8 +496,10 @@ void ClangdLSPServer::onInitialize(const InitializeParams 
&Params,
   if (const auto &Dir = Params.initializationOptions.compilationDatabasePath)
 Opts.CompileCommandsDir = Dir;
   if (Opts.UseDirBasedCDB) {
-BaseCDB = std::make_unique(
-Opts.CompileCommandsDir);
+DirectoryBasedGlobalCompilationDatabase::Options CDBOpts(TFS);
+CDBOpts.CompileCommandsDir = Opts.CompileCommandsDir;
+BaseCDB =
+std::make_unique(CDBOpts);
 BaseCDB = getQueryDriverDatabase(llvm::makeArrayRef(Opts.QueryDriverGlobs),
  std::move(BaseCDB));
   }
@@ -704,6 +706,10 @@ void ClangdLSPServer::onFileEvent(const 
DidChangeWatchedFilesParams &Params) {
   //  - this is useful e.g. when switching git branches, but we're likely to 
see
   //fresh headers but still have the old-branch main-file content
   Server->onFileEvent(Params);
+  // FIXME: observe config files, immediately expire time-based caches, 
reparse:
+  //  - compile_commands.json and compile_flags.txt
+  //  - .clang_format and .clang-tidy
+  //  - .clangd and clangd/config.yaml
 }
 
 void ClangdLSPServer::onCommand(const ExecuteCommandParams &Params,

diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index add0eec4a2c8..41b549cefc7c 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -8,11 +8,15 @@
 
 #include "GlobalCompilationDatabase.h"
 #include "FS.h"
+#include "SourceCode.h"
 #include "support/Logger.h"
 #include "support/Path.h"
+#include "support/ThreadsafeFS.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Tooling/ArgumentsAdjusters.h"
 #include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/CompilationDatabasePluginRegistry.h"
+#include "clang/Tooling/JSONCompilationDatabase.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
@@ -22,6 +26,7 @@
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include 
 #include 
 #include 
@@ -85,33 +90,78 @@ GlobalCompilationDatabase::getFallbackCommand(PathRef File) 
const {
 //  - 1) determine all the paths that might be searched
 //  - 2) acquire the map lock and get-or-create all the DirectoryCache entries
 //  - 3) release the map lock and query the caches as desired
-//
-// FIXME: this should revalidate the cache sometimes
-// FIXME: IO should go through a VFS
 class DirectoryBasedGlobalCompilationDatabase::DirectoryCache {
-  // Absolute canonical path that we're the cache for. (Not case-folded).
-  const std::string Path;
-
-  // True if we've looked for a CDB here and found none.
-  // (This makes it possible for get() to return without taking a lock)
-  // FIXME: this should have an expiry time instead of lasting forever.
-  std::atomic FinalizedNoCDB = {false};
-
-  // Guards following cache state.
+  using stopwatch = std::chrono::steady_clock;
+
+  // CachedFile is used to read a CDB file on disk (e.g. 
compile_commands.json).
+  // It specializes in being able to quickly bail out if the file is unchanged,
+  // which is the common case.
+  // Internally, it stores file metadata so a stat() can verify it's unchanged.
+  // We don't actually cache the content as it's not needed -

[llvm-branch-commits] [clang-tools-extra] 0336ff0 - [clangd] Fix broken JSON test on windows

2020-12-18 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-18T15:11:08+01:00
New Revision: 0336ff0a17e6aec831334aeb50e6685f6b184065

URL: 
https://github.com/llvm/llvm-project/commit/0336ff0a17e6aec831334aeb50e6685f6b184065
DIFF: 
https://github.com/llvm/llvm-project/commit/0336ff0a17e6aec831334aeb50e6685f6b184065.diff

LOG: [clangd] Fix broken JSON test on windows

Added: 


Modified: 
clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp 
b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
index d9fccb835c96..12c986572d8b 100644
--- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
+++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
@@ -432,12 +432,13 @@ TEST_F(DirectoryBasedGlobalCompilationDatabaseCacheTest, 
Cacheable) {
   EXPECT_THAT(FooBar, hasFlag("-DFOOBAR")) << "cdb reloaded";
 
   // compile_commands.json takes precedence over compile_flags.txt.
-  FS.Files["foo/compile_commands.json"] = llvm::formatv(R"json([{
+  FS.Files["foo/compile_commands.json"] =
+  llvm::formatv(R"json([{
 "file": "{0}/foo/dummy.cc",
 "command": "clang -DBAZ dummy.cc",
 "directory": "{0}/foo",
   }])json",
-testRoot());
+llvm::sys::path::convert_to_slash(testRoot()));
   EXPECT_EQ(FooBar, lookupCDB(GDB, testPath("foo/test.cc"), Stale))
   << "cache still valid";
   auto Baz = lookupCDB(GDB, testPath("foo/test.cc"), Fresh);



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] c46c7c9 - [clangd] Smarter hover on auto and decltype

2020-12-18 Thread Sam McCall via llvm-branch-commits

Author: Quentin Chateau
Date: 2020-12-18T16:27:09+01:00
New Revision: c46c7c9bcf9752971fe4bbcf67140c99066ad2e0

URL: 
https://github.com/llvm/llvm-project/commit/c46c7c9bcf9752971fe4bbcf67140c99066ad2e0
DIFF: 
https://github.com/llvm/llvm-project/commit/c46c7c9bcf9752971fe4bbcf67140c99066ad2e0.diff

LOG: [clangd] Smarter hover on auto and decltype

Only show the keyword as the hover "Name".

Show whether the type is deduced or undeduced as
the hover "Documentation".

Show the deduced type (if any) as the "Definition".

Don't show any hover information for:
- the "auto" word of "decltype(auto)"
- "auto" in lambda parameters
- "auto" in template arguments

---

This diff is a suggestion based on what @sammccall  suggested in 
https://reviews.llvm.org/D92977 about hover on "auto". It somehow "hacks" onto 
the "Documentation" and "Definition" fields of `HoverInfo`. It sure looks good 
on VSCode, let me know if this seem acceptable to you.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D93227

Added: 


Modified: 
clang-tools-extra/clangd/AST.cpp
clang-tools-extra/clangd/AST.h
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/refactor/tweaks/ExpandAutoType.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/AST.cpp 
b/clang-tools-extra/clangd/AST.cpp
index b0c9ecab1e05..c5f87af86319 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -350,8 +350,7 @@ class DeducedTypeVisitor : public 
RecursiveASTVisitor {
   return true;
 
 if (auto *AT = D->getType()->getContainedAutoType()) {
-  if (!AT->getDeducedType().isNull())
-DeducedType = AT->getDeducedType();
+  DeducedType = AT->desugar();
 }
 return true;
   }

diff  --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h
index 1e3447376c10..b603964189e8 100644
--- a/clang-tools-extra/clangd/AST.h
+++ b/clang-tools-extra/clangd/AST.h
@@ -109,6 +109,7 @@ QualType declaredType(const TypeDecl *D);
 
 /// Retrieves the deduced type at a given location (auto, decltype).
 /// It will return the underlying type.
+/// If the type is an undeduced auto, returns the type itself.
 llvm::Optional getDeducedType(ASTContext &, SourceLocation Loc);
 
 /// Gets the nested name specifier necessary for spelling \p ND in \p

diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index e461c7c43364..b5eda93ddbbc 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
@@ -550,29 +551,6 @@ HoverInfo getHoverContents(const NamedDecl *D, const 
SymbolIndex *Index) {
   return HI;
 }
 
-/// Generate a \p Hover object given the type \p T.
-HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx,
-   const SymbolIndex *Index,
-   bool SuppressScope = false) {
-  HoverInfo HI;
-
-  if (const auto *D = T->getAsTagDecl()) {
-HI.Name = printName(ASTCtx, *D);
-HI.Kind = index::getSymbolInfo(D).Kind;
-
-const auto *CommentD = getDeclForComment(D);
-HI.Documentation = getDeclComment(ASTCtx, *CommentD);
-enhanceFromIndex(HI, *CommentD, Index);
-  } else {
-// Builtin types
-auto Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
-Policy.SuppressTagKeyword = true;
-Policy.SuppressScope = SuppressScope;
-HI.Name = T.getAsString(Policy);
-  }
-  return HI;
-}
-
 /// Generate a \p Hover object given the macro \p MacroDecl.
 HoverInfo getHoverContents(const DefinedMacro &Macro, ParsedAST &AST) {
   HoverInfo HI;
@@ -608,6 +586,52 @@ HoverInfo getHoverContents(const DefinedMacro &Macro, 
ParsedAST &AST) {
   return HI;
 }
 
+llvm::Optional getThisExprHoverContents(const CXXThisExpr *CTE,
+   ASTContext &ASTCtx) {
+  QualType OriginThisType = CTE->getType()->getPointeeType();
+  QualType ClassType = declaredType(OriginThisType->getAsTagDecl());
+  // For partial specialization class, origin `this` pointee type will be
+  // parsed as `InjectedClassNameType`, which will ouput template arguments
+  // like "type-parameter-0-0". So we retrieve user written class type in this
+  // case.
+  QualType PrettyThisType = ASTCtx.getPointerType(
+  QualType(ClassType.getTypePtr(), OriginThisType.getCVRQualifiers()));
+
+  auto Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
+  Policy.SuppressTagKeyword = true;
+  Policy.SuppressScope = true;
+  HoverInfo HI;
+  HI.Name = "this";
+  HI.Definition = PrettyThisType.getAsString(Poli

[llvm-branch-commits] [clang-tools-extra] 95c7b6c - [clangd] zap a few warnings

2020-12-18 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-18T16:34:34+01:00
New Revision: 95c7b6cadbc9a3d4376ef44edbeb3c8bb5b8d7fc

URL: 
https://github.com/llvm/llvm-project/commit/95c7b6cadbc9a3d4376ef44edbeb3c8bb5b8d7fc
DIFF: 
https://github.com/llvm/llvm-project/commit/95c7b6cadbc9a3d4376ef44edbeb3c8bb5b8d7fc.diff

LOG: [clangd] zap a few warnings

Added: 


Modified: 
clang-tools-extra/clangd/DumpAST.cpp
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/index/remote/Client.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/DumpAST.cpp 
b/clang-tools-extra/clangd/DumpAST.cpp
index 12698b42ef3e..8f1b3f3a1aae 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -143,6 +143,7 @@ class DumpVisitor : public RecursiveASTVisitor 
{
   TEMPLATE_ARGUMENT_KIND(Declaration);
   TEMPLATE_ARGUMENT_KIND(Template);
   TEMPLATE_ARGUMENT_KIND(TemplateExpansion);
+  TEMPLATE_ARGUMENT_KIND(UncommonValue);
 #undef TEMPLATE_ARGUMENT_KIND
 }
 llvm_unreachable("Unhandled ArgKind enum");

diff  --git a/clang-tools-extra/clangd/FindTarget.cpp 
b/clang-tools-extra/clangd/FindTarget.cpp
index 3afd65522680..c5c7d71be661 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -1069,6 +1069,7 @@ class ExplicitReferenceCollector
 case TemplateArgument::Pack:
 case TemplateArgument::Type:
 case TemplateArgument::Expression:
+case TemplateArgument::UncommonValue:
   break; // Handled by VisitType and VisitExpression.
 };
 return RecursiveASTVisitor::TraverseTemplateArgumentLoc(A);

diff  --git a/clang-tools-extra/clangd/index/remote/Client.cpp 
b/clang-tools-extra/clangd/index/remote/Client.cpp
index b09dbf915e46..a153a8812baf 100644
--- a/clang-tools-extra/clangd/index/remote/Client.cpp
+++ b/clang-tools-extra/clangd/index/remote/Client.cpp
@@ -152,7 +152,8 @@ class IndexClient : public clangd::SymbolIndex {
   });
   }
 
-  llvm::unique_function indexedFiles() const {
+  llvm::unique_function
+  indexedFiles() const override {
 // FIXME: For now we always return "false" regardless of whether the file
 //was indexed or not. A possible implementation could be based on
 //the idea that we do not want to send a request at every



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] b061564 - [clangd] Make our printing policies for Hover more consistent, especially tags

2020-12-18 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-19T00:52:55+01:00
New Revision: b0615642f647bea1483659f1e14515a836015254

URL: 
https://github.com/llvm/llvm-project/commit/b0615642f647bea1483659f1e14515a836015254
DIFF: 
https://github.com/llvm/llvm-project/commit/b0615642f647bea1483659f1e14515a836015254.diff

LOG: [clangd] Make our printing policies for Hover more consistent, especially 
tags

Different cases were using a bunch of different variants of the printing policy.
Each of these had something going for it, but the result was inconsistent.

Goals:
  - single printing policy used (almost) everywhere
  - avoid unidiomatic tags like `class vector`
  - be informative and easy to understand

For tags, the solution I wound up with is: we print only the outer tag and only
in the simplest cases where this elaboration won't cause confusion.

For example:
 - class X
 - enum Foo
 - vector
 - X*

This seems to strike a nice balance of providing plenty of info/context in 
common
cases while never being confusing.

Differential Revision: https://reviews.llvm.org/D93553

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index b5eda93ddbbc..6d707c8d1521 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -49,16 +49,13 @@ namespace clang {
 namespace clangd {
 namespace {
 
-PrintingPolicy printingPolicyForDecls(PrintingPolicy Base) {
-  PrintingPolicy Policy(Base);
-
-  Policy.AnonymousTagLocations = false;
-  Policy.TerseOutput = true;
-  Policy.PolishForDeclaration = true;
-  Policy.ConstantsAsWritten = true;
-  Policy.SuppressTagKeyword = false;
-
-  return Policy;
+PrintingPolicy getPrintingPolicy(PrintingPolicy Base) {
+  Base.AnonymousTagLocations = false;
+  Base.TerseOutput = true;
+  Base.PolishForDeclaration = true;
+  Base.ConstantsAsWritten = true;
+  Base.SuppressTemplateArgsInCXXConstructors = true;
+  return Base;
 }
 
 /// Given a declaration \p D, return a human-readable string representing the
@@ -108,26 +105,33 @@ std::string getNamespaceScope(const Decl *D) {
   return "";
 }
 
-std::string printDefinition(const Decl *D) {
+std::string printDefinition(const Decl *D, const PrintingPolicy &PP) {
   std::string Definition;
   llvm::raw_string_ostream OS(Definition);
-  PrintingPolicy Policy =
-  printingPolicyForDecls(D->getASTContext().getPrintingPolicy());
-  Policy.IncludeTagDefinition = false;
-  Policy.SuppressTemplateArgsInCXXConstructors = true;
-  Policy.SuppressTagKeyword = true;
-  D->print(OS, Policy);
+  D->print(OS, PP);
   OS.flush();
   return Definition;
 }
 
-std::string printType(QualType QT, const PrintingPolicy &Policy) {
+std::string printType(QualType QT, const PrintingPolicy &PP) {
   // TypePrinter doesn't resolve decltypes, so resolve them here.
   // FIXME: This doesn't handle composite types that contain a decltype in 
them.
   // We should rather have a printing policy for that.
   while (!QT.isNull() && QT->isDecltypeType())
 QT = QT->getAs()->getUnderlyingType();
-  return QT.getAsString(Policy);
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+  // Special case: if the outer type is a tag type without qualifiers, then
+  // include the tag for extra clarity.
+  // This isn't very idiomatic, so don't attempt it for complex cases, 
including
+  // pointers/references, template specializations, etc.
+  if (!QT.isNull() && !QT.hasQualifiers() && PP.SuppressTagKeyword) {
+if (auto *TT = llvm::dyn_cast(QT.getTypePtr()))
+  OS << TT->getDecl()->getKindName() << " ";
+  }
+  OS.flush();
+  QT.print(OS, PP);
+  return Result;
 }
 
 std::string printType(const TemplateTypeParmDecl *TTP) {
@@ -291,15 +295,15 @@ const Expr *getDefaultArg(const ParmVarDecl *PVD) {
 }
 
 HoverInfo::Param toHoverInfoParam(const ParmVarDecl *PVD,
-  const PrintingPolicy &Policy) {
+  const PrintingPolicy &PP) {
   HoverInfo::Param Out;
-  Out.Type = printType(PVD->getType(), Policy);
+  Out.Type = printType(PVD->getType(), PP);
   if (!PVD->getName().empty())
 Out.Name = PVD->getNameAsString();
   if (const Expr *DefArg = getDefaultArg(PVD)) {
 Out.Default.emplace();
 llvm::raw_string_ostream OS(*Out.Default);
-DefArg->printPretty(OS, nullptr, Policy);
+DefArg->printPretty(OS, nullptr, PP);
   }
   return Out;
 }
@@ -307,10 +311,10 @@ HoverInfo::Param toHoverInfoParam(const ParmVarDecl *PVD,
 // Populates Type, ReturnType, and Parameters for function-like decls.
 void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
const FunctionDecl *FD,
-   const PrintingPolicy &Policy) {
+   const PrintingPolicy &PP) {
   HI.Paramet

[llvm-branch-commits] [clang-tools-extra] 2fced5a - [clangd] Don't cancel requests based on "updates" with same content

2020-12-18 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-19T02:03:40+01:00
New Revision: 2fced5a07b45ef527ac00a13e63bfca61e407ee3

URL: 
https://github.com/llvm/llvm-project/commit/2fced5a07b45ef527ac00a13e63bfca61e407ee3
DIFF: 
https://github.com/llvm/llvm-project/commit/2fced5a07b45ef527ac00a13e63bfca61e407ee3.diff

LOG: [clangd] Don't cancel requests based on "updates" with same content

There's an unfortunate collision between two features:
 - we implicitly cancel certain requests when the file changes, to avoid
   the queue getting clogged building old revisions to service stale requests
 - we "reparse-if-needed" by synthesizing a file change, e.g. on didSave

We could explicitly mark these synthetic requests to avoid this, but
looking for changes in file content clutters our APIs less and is
arguably the correct thing to do in any case.

Fixes https://github.com/clangd/clangd/issues/620

Added: 


Modified: 
clang-tools-extra/clangd/TUScheduler.cpp
clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/TUScheduler.cpp 
b/clang-tools-extra/clangd/TUScheduler.cpp
index 443abcfe847a..813a000b41a5 100644
--- a/clang-tools-extra/clangd/TUScheduler.cpp
+++ b/clang-tools-extra/clangd/TUScheduler.cpp
@@ -385,7 +385,7 @@ class ASTWorker {
 ParsingCallbacks &Callbacks);
   ~ASTWorker();
 
-  void update(ParseInputs Inputs, WantDiagnostics);
+  void update(ParseInputs Inputs, WantDiagnostics, bool ContentChanged);
   void
   runWithAST(llvm::StringRef Name,
  llvm::unique_function)> Action,
@@ -419,6 +419,18 @@ class ASTWorker {
   bool isASTCached() const;
 
 private:
+  // Details of an update request that are relevant to scheduling.
+  struct UpdateType {
+// Do we want diagnostics from this version?
+// If Yes, we must always build this version.
+// If No, we only need to build this version if it's read.
+// If Auto, we build if it's read or if the debounce expires.
+WantDiagnostics Diagnostics;
+// Did the main-file content of the document change?
+// If so, we're allowed to cancel certain invalidated preceding reads.
+bool ContentChanged;
+  };
+
   /// Publishes diagnostics for \p Inputs. It will build an AST or reuse the
   /// cached one if applicable. Assumes LatestPreamble is compatible for \p
   /// Inputs.
@@ -431,9 +443,10 @@ class ASTWorker {
   void run();
   /// Signal that run() should finish processing pending requests and exit.
   void stop();
+
   /// Adds a new task to the end of the request queue.
   void startTask(llvm::StringRef Name, llvm::unique_function Task,
- llvm::Optional UpdateType,
+ llvm::Optional Update,
  TUScheduler::ASTActionInvalidation);
 
   /// Determines the next action to perform.
@@ -449,7 +462,7 @@ class ASTWorker {
 std::string Name;
 steady_clock::time_point AddTime;
 Context Ctx;
-llvm::Optional UpdateType;
+llvm::Optional Update;
 TUScheduler::ASTActionInvalidation InvalidationPolicy;
 Canceler Invalidate;
   };
@@ -598,7 +611,8 @@ ASTWorker::~ASTWorker() {
 #endif
 }
 
-void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags) {
+void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags,
+   bool ContentChanged) {
   std::string TaskName = llvm::formatv("Update ({0})", Inputs.Version);
   auto Task = [=]() mutable {
 // Get the actual command as `Inputs` does not have a command.
@@ -679,7 +693,8 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics 
WantDiags) {
 });
 return;
   };
-  startTask(TaskName, std::move(Task), WantDiags, TUScheduler::NoInvalidation);
+  startTask(TaskName, std::move(Task), UpdateType{WantDiags, ContentChanged},
+TUScheduler::NoInvalidation);
 }
 
 void ASTWorker::runWithAST(
@@ -723,7 +738,7 @@ void ASTWorker::runWithAST(
  FileInputs.Version);
 Action(InputsAndAST{FileInputs, **AST});
   };
-  startTask(Name, std::move(Task), /*UpdateType=*/None, Invalidation);
+  startTask(Name, std::move(Task), /*Update=*/None, Invalidation);
 }
 
 void PreambleThread::build(Request Req) {
@@ -960,7 +975,7 @@ void ASTWorker::stop() {
 
 void ASTWorker::startTask(llvm::StringRef Name,
   llvm::unique_function Task,
-  llvm::Optional UpdateType,
+  llvm::Optional Update,
   TUScheduler::ASTActionInvalidation Invalidation) {
   if (RunSync) {
 assert(!Done && "running a task after stop()");
@@ -974,11 +989,11 @@ void ASTWorker::startTask(llvm::StringRef Name,
 std::lock_guard Lock(Mutex);
 assert(!Done && "running a task after stop()");
 // Cancel any requests invalidated by this request.
-if (UpdateType) {
+if (Update && Update->ContentChanged) {
   for (auto &R : ll

[llvm-branch-commits] [clang-tools-extra] 2b62e62 - [clangd] Fix windows path handling in .clang-tidy parsing

2020-12-18 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-19T02:24:25+01:00
New Revision: 2b62e62328841b7d2dc01e390e13fb9151d06263

URL: 
https://github.com/llvm/llvm-project/commit/2b62e62328841b7d2dc01e390e13fb9151d06263
DIFF: 
https://github.com/llvm/llvm-project/commit/2b62e62328841b7d2dc01e390e13fb9151d06263.diff

LOG: [clangd] Fix windows path handling in .clang-tidy parsing

Added: 


Modified: 
clang-tools-extra/clangd/TidyProvider.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/TidyProvider.cpp 
b/clang-tools-extra/clangd/TidyProvider.cpp
index c12dab7e2e5e..0a9f12221287 100644
--- a/clang-tools-extra/clangd/TidyProvider.cpp
+++ b/clang-tools-extra/clangd/TidyProvider.cpp
@@ -106,12 +106,17 @@ class DotClangTidyTree {
 llvm::SmallVector Caches;
 {
   std::lock_guard Lock(Mu);
-  for (auto I = path::begin(Parent, path::Style::posix),
-E = path::end(Parent);
-   I != E; ++I) {
+  for (auto I = path::begin(Parent), E = path::end(Parent); I != E; ++I) {
 assert(I->end() >= Parent.begin() && I->end() <= Parent.end() &&
"Canonical path components should be substrings");
 llvm::StringRef Ancestor(Parent.begin(), I->end() - Parent.begin());
+#ifdef _WIN32
+// C:\ is an ancestor, but skip its (relative!) parent C:.
+if (Ancestor.size() == 2 && Ancestor.back() == ':')
+  continue;
+#endif
+assert(path::is_absolute(Ancestor));
+
 auto It = Cache.find(Ancestor);
 
 // Assemble the actual config file path only if needed.



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 3fa2d37 - [clangd][NFC] Improve clangd status messages

2020-12-21 Thread Sam McCall via llvm-branch-commits

Author: Quentin Chateau
Date: 2020-12-21T20:19:25+01:00
New Revision: 3fa2d37eb3f8acddcfde749ca822f2cc7d900cbb

URL: 
https://github.com/llvm/llvm-project/commit/3fa2d37eb3f8acddcfde749ca822f2cc7d900cbb
DIFF: 
https://github.com/llvm/llvm-project/commit/3fa2d37eb3f8acddcfde749ca822f2cc7d900cbb.diff

LOG: [clangd][NFC] Improve clangd status messages

clangd actions have various naming schemes, the most
common being PascalCase. This commit applies PascalCase
to all clangd actions, and fix the status rendering
in `renderTUAction` to look more consistent.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D93546

Added: 


Modified: 
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/TUScheduler.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index 8b0d0591abe7..b760b31c0b87 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -621,7 +621,7 @@ void ClangdServer::typeHierarchy(PathRef File, Position 
Pos, int Resolve,
 File));
   };
 
-  WorkScheduler.runWithAST("Type Hierarchy", File, std::move(Action));
+  WorkScheduler.runWithAST("TypeHierarchy", File, std::move(Action));
 }
 
 void ClangdServer::resolveTypeHierarchy(
@@ -642,7 +642,7 @@ void ClangdServer::prepareCallHierarchy(
   return CB(InpAST.takeError());
 CB(clangd::prepareCallHierarchy(InpAST->AST, Pos, File));
   };
-  WorkScheduler.runWithAST("Call Hierarchy", File, std::move(Action));
+  WorkScheduler.runWithAST("CallHierarchy", File, std::move(Action));
 }
 
 void ClangdServer::incomingCalls(
@@ -678,7 +678,7 @@ void ClangdServer::documentSymbols(llvm::StringRef File,
   return CB(InpAST.takeError());
 CB(clangd::getDocumentSymbols(InpAST->AST));
   };
-  WorkScheduler.runWithAST("documentSymbols", File, std::move(Action),
+  WorkScheduler.runWithAST("DocumentSymbols", File, std::move(Action),
TUScheduler::InvalidateOnUpdate);
 }
 
@@ -690,7 +690,7 @@ void ClangdServer::foldingRanges(llvm::StringRef File,
   return CB(InpAST.takeError());
 CB(clangd::getFoldingRanges(InpAST->AST));
   };
-  WorkScheduler.runWithAST("foldingRanges", File, std::move(Action),
+  WorkScheduler.runWithAST("FoldingRanges", File, std::move(Action),
TUScheduler::InvalidateOnUpdate);
 }
 

diff  --git a/clang-tools-extra/clangd/TUScheduler.cpp 
b/clang-tools-extra/clangd/TUScheduler.cpp
index 813a000b41a5..7a858664faa5 100644
--- a/clang-tools-extra/clangd/TUScheduler.cpp
+++ b/clang-tools-extra/clangd/TUScheduler.cpp
@@ -1220,7 +1220,7 @@ std::string renderTUAction(const PreambleAction PA, const 
ASTAction &AA) {
   }
   if (Result.empty())
 return "idle";
-  return llvm::join(Result, ",");
+  return llvm::join(Result, ", ");
 }
 
 } // namespace



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] b8c3715 - [clangd] Trim memory periodically when using glibc malloc

2020-12-21 Thread Sam McCall via llvm-branch-commits

Author: Quentin Chateau
Date: 2020-12-22T08:54:28+01:00
New Revision: b8c37153d5393aad96feefe0b4689b7b62bc160d

URL: 
https://github.com/llvm/llvm-project/commit/b8c37153d5393aad96feefe0b4689b7b62bc160d
DIFF: 
https://github.com/llvm/llvm-project/commit/b8c37153d5393aad96feefe0b4689b7b62bc160d.diff

LOG: [clangd] Trim memory periodically when using glibc malloc

This diff addresses the issue of the ever increasing memory usage of clangd. 
The key to understand what happens is to use `malloc_stats()`: malloc arenas 
keep getting bigger, although the actual memory used does not. It seems some 
operations while bulding the indices (both dynamic and background) create this 
problem. Specifically, 'FileSymbols::update' and 'FileSymbols::buildIndex' seem 
especially affected.

This diff adds a call to `malloc_trim()` periodically in
ClangdLSPServer.

Fixes: https://github.com/clangd/clangd/issues/251
Fixes: https://github.com/clangd/clangd/issues/115

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D93452

Added: 


Modified: 
clang-tools-extra/clangd/CMakeLists.txt
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdLSPServer.h
clang-tools-extra/clangd/Features.inc.in
clang-tools-extra/clangd/tool/ClangdMain.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/CMakeLists.txt 
b/clang-tools-extra/clangd/CMakeLists.txt
index 919457f216c1..9e62e0948027 100644
--- a/clang-tools-extra/clangd/CMakeLists.txt
+++ b/clang-tools-extra/clangd/CMakeLists.txt
@@ -14,9 +14,12 @@ if (NOT DEFINED CLANGD_BUILD_XPC)
   unset(CLANGD_BUILD_XPC_DEFAULT)
 endif ()
 
+option(CLANGD_MALLOC_TRIM "Call malloc_trim(3) periodically in Clangd. (only 
takes effect when using glibc)" ON)
+
 llvm_canonicalize_cmake_booleans(
   CLANGD_BUILD_XPC
   CLANGD_ENABLE_REMOTE
+  CLANGD_MALLOC_TRIM
   LLVM_ENABLE_ZLIB
 )
 

diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp 
b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index b32c9e13973b..0c42f95fb594 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -178,6 +178,7 @@ class ClangdLSPServer::MessageHandler : public 
Transport::MessageHandler {
 } else if (auto Handler = Notifications.lookup(Method)) {
   Handler(std::move(Params));
   Server.maybeExportMemoryProfile();
+  Server.maybeCleanupMemory();
 } else {
   log("unhandled notification {0}", Method);
 }
@@ -453,6 +454,7 @@ void ClangdLSPServer::callRaw(StringRef Method, 
llvm::json::Value Params,
 
 void ClangdLSPServer::notify(llvm::StringRef Method, llvm::json::Value Params) 
{
   log("--> {0}", Method);
+  maybeCleanupMemory();
   std::lock_guard Lock(TranspWriter);
   Transp.notify(Method, std::move(Params));
 }
@@ -1301,6 +1303,27 @@ void ClangdLSPServer::maybeExportMemoryProfile() {
   NextProfileTime = Now + ProfileInterval;
 }
 
+void ClangdLSPServer::maybeCleanupMemory() {
+  // Memory cleanup is probably expensive, throttle it
+  static constexpr auto MemoryCleanupInterval = std::chrono::minutes(1);
+
+  if (!Opts.MemoryCleanup)
+return;
+
+  // FIXME: this can probably be done without a mutex
+  // and the logic could be shared with maybeExportMemoryProfile
+  {
+auto Now = std::chrono::steady_clock::now();
+std::lock_guard Lock(NextMemoryCleanupTimeMutex);
+if (Now < NextMemoryCleanupTime)
+  return;
+NextMemoryCleanupTime = Now + MemoryCleanupInterval;
+  }
+
+  vlog("Calling memory cleanup callback");
+  Opts.MemoryCleanup();
+}
+
 // FIXME: This function needs to be properly tested.
 void ClangdLSPServer::onChangeConfiguration(
 const DidChangeConfigurationParams &Params) {
@@ -1507,8 +1530,9 @@ ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
 MsgHandler->bind("textDocument/foldingRange", 
&ClangdLSPServer::onFoldingRange);
   // clang-format on
 
-  // Delay first profile until we've finished warming up.
-  NextProfileTime = std::chrono::steady_clock::now() + std::chrono::minutes(1);
+  // Delay first profile and memory cleanup until we've finished warming up.
+  NextMemoryCleanupTime = NextProfileTime =
+  std::chrono::steady_clock::now() + std::chrono::minutes(1);
 }
 
 ClangdLSPServer::~ClangdLSPServer() {
@@ -1621,6 +1645,10 @@ void ClangdLSPServer::onDiagnosticsReady(PathRef File, 
llvm::StringRef Version,
 void ClangdLSPServer::onBackgroundIndexProgress(
 const BackgroundQueue::Stats &Stats) {
   static const char ProgressToken[] = "backgroundIndexProgress";
+
+  // The background index did some work, maybe we need to cleanup
+  maybeCleanupMemory();
+
   std::lock_guard Lock(BackgroundIndexProgressMutex);
 
   auto NotifyProgress = [this](const BackgroundQueue::Stats &Stats) {

diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.h 
b/clang-tools-extra/clangd/ClangdLSPServer.h
index e65fc0e8a006..b5f9d2c9d766 100644
-

[llvm-branch-commits] [clang-tools-extra] 3dbe471 - [clangd] Use atomics instead of locks to track periodic memory trimming

2020-12-22 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-22T22:32:22+01:00
New Revision: 3dbe471a260392ec63dda8deb2709160afc56dde

URL: 
https://github.com/llvm/llvm-project/commit/3dbe471a260392ec63dda8deb2709160afc56dde
DIFF: 
https://github.com/llvm/llvm-project/commit/3dbe471a260392ec63dda8deb2709160afc56dde.diff

LOG: [clangd] Use atomics instead of locks to track periodic memory trimming

Instead of always locking/unlocking a contended mutex, we now do one atomic read
in the common case, and one read + one exchange if the timer has expried.

Also use this for memory profiling which has similar/compatible requirements.

Differential Revision: https://reviews.llvm.org/D93726

Added: 


Modified: 
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdLSPServer.h
clang-tools-extra/clangd/support/Threading.cpp
clang-tools-extra/clangd/support/Threading.h
clang-tools-extra/clangd/unittests/support/ThreadingTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp 
b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 0c42f95fb594..c606ccae4fdc 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -1285,13 +1285,7 @@ void ClangdLSPServer::publishDiagnostics(
 }
 
 void ClangdLSPServer::maybeExportMemoryProfile() {
-  if (!trace::enabled())
-return;
-  // Profiling might be expensive, so we throttle it to happen once every 5
-  // minutes.
-  static constexpr auto ProfileInterval = std::chrono::minutes(5);
-  auto Now = std::chrono::steady_clock::now();
-  if (Now < NextProfileTime)
+  if (!trace::enabled() || !ShouldProfile())
 return;
 
   static constexpr trace::Metric MemoryUsage(
@@ -1300,27 +1294,11 @@ void ClangdLSPServer::maybeExportMemoryProfile() {
   MemoryTree MT;
   profile(MT);
   record(MT, "clangd_lsp_server", MemoryUsage);
-  NextProfileTime = Now + ProfileInterval;
 }
 
 void ClangdLSPServer::maybeCleanupMemory() {
-  // Memory cleanup is probably expensive, throttle it
-  static constexpr auto MemoryCleanupInterval = std::chrono::minutes(1);
-
-  if (!Opts.MemoryCleanup)
+  if (!Opts.MemoryCleanup || !ShouldCleanupMemory())
 return;
-
-  // FIXME: this can probably be done without a mutex
-  // and the logic could be shared with maybeExportMemoryProfile
-  {
-auto Now = std::chrono::steady_clock::now();
-std::lock_guard Lock(NextMemoryCleanupTimeMutex);
-if (Now < NextMemoryCleanupTime)
-  return;
-NextMemoryCleanupTime = Now + MemoryCleanupInterval;
-  }
-
-  vlog("Calling memory cleanup callback");
   Opts.MemoryCleanup();
 }
 
@@ -1481,10 +1459,15 @@ void ClangdLSPServer::onAST(const ASTParams &Params,
 ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
  const ThreadsafeFS &TFS,
  const ClangdLSPServer::Options &Opts)
-: BackgroundContext(Context::current().clone()), Transp(Transp),
+: ShouldProfile(/*Period=*/std::chrono::minutes(5),
+/*Delay=*/std::chrono::minutes(1)),
+  ShouldCleanupMemory(/*Period=*/std::chrono::minutes(1),
+  /*Delay=*/std::chrono::minutes(1)),
+  BackgroundContext(Context::current().clone()), Transp(Transp),
   MsgHandler(new MessageHandler(*this)), TFS(TFS),
   SupportedSymbolKinds(defaultSymbolKinds()),
   SupportedCompletionItemKinds(defaultCompletionItemKinds()), Opts(Opts) {
+
   // clang-format off
   MsgHandler->bind("initialize", &ClangdLSPServer::onInitialize);
   MsgHandler->bind("initialized", &ClangdLSPServer::onInitialized);
@@ -1529,10 +1512,6 @@ ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
   if (Opts.FoldingRanges)
 MsgHandler->bind("textDocument/foldingRange", 
&ClangdLSPServer::onFoldingRange);
   // clang-format on
-
-  // Delay first profile and memory cleanup until we've finished warming up.
-  NextMemoryCleanupTime = NextProfileTime =
-  std::chrono::steady_clock::now() + std::chrono::minutes(1);
 }
 
 ClangdLSPServer::~ClangdLSPServer() {

diff  --git a/clang-tools-extra/clangd/ClangdLSPServer.h 
b/clang-tools-extra/clangd/ClangdLSPServer.h
index b5f9d2c9d766..a41bc5666af3 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -19,6 +19,7 @@
 #include "support/Context.h"
 #include "support/MemoryTree.h"
 #include "support/Path.h"
+#include "support/Threading.h"
 #include "clang/Tooling/Core/Replacement.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringSet.h"
@@ -186,18 +187,12 @@ class ClangdLSPServer : private ClangdServer::Callbacks {
   /// Runs profiling and exports memory usage metrics if tracing is enabled and
   /// profiling hasn't happened recently.
   void maybeExportMemoryProfile();
+  PeriodicThrottler ShouldProfile;
 
   /// Run the MemoryCleanup callback if it's time.
   /// This meth

[llvm-branch-commits] [clang-tools-extra] f7a2612 - [clangd] Release notes for b8c37153d5393aad96

2020-12-22 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-22T22:58:45+01:00
New Revision: f7a26127f21fb1ca8252879ca647835ea7c5903d

URL: 
https://github.com/llvm/llvm-project/commit/f7a26127f21fb1ca8252879ca647835ea7c5903d
DIFF: 
https://github.com/llvm/llvm-project/commit/f7a26127f21fb1ca8252879ca647835ea7c5903d.diff

LOG: [clangd] Release notes for b8c37153d5393aad96

Added: 


Modified: 
clang-tools-extra/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 450b80fd4581..2960aad5a556 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -47,7 +47,17 @@ Major New Features
 Improvements to clangd
 --
 
-The improvements are...
+- clangd's memory usage is significantly reduced on most Linux systems.
+  In particular, memory usage should not increase dramatically over time.
+
+  The standard allocator on most systems is glibc's ptmalloc2, and it creates
+  disproportionately large heaps when handling clangd's allocation patterns.
+  By default, clangd will now periodically call ``malloc_trim`` to release free
+  pages on glibc systems.
+
+  Users of other allocators (such as ``jemalloc`` or ``tcmalloc``) on glibc
+  systems can disable this using ``--malloc_trim=0`` or the CMake flag
+  ``-DCLANGD_MALLOC_TRIM=0``.
 
 Improvements to clang-doc
 -



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 74b3ace - [clangd] Fix case mismatch crash on in CDB on windows after 92dd077af1ff8

2020-12-23 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-23T22:42:45+01:00
New Revision: 74b3acefc7b6355e89bb9b09dc88a5948f65c342

URL: 
https://github.com/llvm/llvm-project/commit/74b3acefc7b6355e89bb9b09dc88a5948f65c342
DIFF: 
https://github.com/llvm/llvm-project/commit/74b3acefc7b6355e89bb9b09dc88a5948f65c342.diff

LOG: [clangd] Fix case mismatch crash on in CDB on windows after 92dd077af1ff8

See https://github.com/clangd/clangd/issues/631

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index 41b549cefc7c..86375fa11d3b 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -511,11 +511,14 @@ void 
DirectoryBasedGlobalCompilationDatabase::broadcastCDB(
   // Given that we know that CDBs have been moved/generated, don't trust 
caches.
   // (This should be rare, so it's OK to add a little latency).
   constexpr auto IgnoreCache = std::chrono::steady_clock::time_point::max();
-  for (DirectoryCache *Dir : getDirectoryCaches(FileAncestors)) {
+  auto DirectoryCaches = getDirectoryCaches(FileAncestors);
+  assert(DirectoryCaches.size() == FileAncestors.size());
+  for (unsigned I = 0; I < DirectoryCaches.size(); ++I) {
 bool ShouldBroadcast = false;
-if (Dir->get(Opts.TFS, ShouldBroadcast, /*FreshTime=*/IgnoreCache,
- /*FreshTimeMissing=*/IgnoreCache))
-  DirectoryHasCDB.find(Dir->Path)->setValue(true);
+if (DirectoryCaches[I]->get(Opts.TFS, ShouldBroadcast,
+/*FreshTime=*/IgnoreCache,
+/*FreshTimeMissing=*/IgnoreCache))
+  DirectoryHasCDB.find(FileAncestors[I])->setValue(true);
   }
 
   std::vector GovernedFiles;



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] f0c41f1 - [clangd] Release notes for 11.x

2020-08-10 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-08-10T12:38:24+02:00
New Revision: f0c41f1d63627a29055474e6df73f78761ca8213

URL: 
https://github.com/llvm/llvm-project/commit/f0c41f1d63627a29055474e6df73f78761ca8213
DIFF: 
https://github.com/llvm/llvm-project/commit/f0c41f1d63627a29055474e6df73f78761ca8213.diff

LOG: [clangd] Release notes for 11.x

Added: 


Modified: 
clang-tools-extra/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 0238ef5149b0..9f96d6eab38e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -47,7 +47,196 @@ Major New Features
 Improvements to clangd
 --
 
-The improvements are...
+Performance
+^^^
+
+- Eliminated long delays after adding/removing includes ("async preambles")
+
+- Faster indexing
+
+- Less memory used to index headers used by open files ("dynamic index")
+
+- Many requests are implicitly cancelled rather than queued when the file is
+  edited, preventing a backlog
+
+- Background indexing can be selectively disabled per-path through config
+
+Selecting and targeting
+^^^
+
+- Improved understanding and selection around broken code ("recovery AST")
+
+- Operations like "go-to-definition" will target things on the left of the
+  cursor, if there is nothing eligible on the right.
+
+- Arguments to ``assert()``-like macros can be properly selected.
+
+Diagnostics
+^^^
+
+- When a header is saved, diagnostics for files that use it are updated.
+
+- Calls ``std::make_unique`` produce diagnostics for the constructor call.
+  (Template functions *in general* are not expanded for performance reasons).
+
+- Diagnostics update more quickly for files that build quickly (no 500ms delay)
+
+- Automatic fixes are offered even when they affect macro arguments.
+
+- Warnings from included headers are not shown (but errors still are).
+
+- A handful of high-quality clang-tidy checks are enabled by default:
+
+  - readability-misleading-indentation,
+
+  - readability-deleted-default,
+
+  - bugprone-integer-division,
+
+  - bugprone-sizeof-expression,
+
+  - bugprone-suspicious-missing-comma,
+
+  - bugprone-unused-raii,
+
+  - bugprone-unused-return-value,
+
+  - misc-unused-using-decls,
+
+  - misc-unused-alias-decls,
+
+  - misc-definitions-in-headers
+
+Refactorings
+
+
+- Rename applies across the project, using the index.
+
+- Accuracy of rename improved in many places.
+
+- New refactoring: add using declaration for qualified name.
+
+- New refactoring: move function definition out-of-line.
+
+Code completion
+^^^
+
+- Function call parentheses are not inserted if they already exist.
+
+- Completion of ``#include`` filenames triggers earlier (after ``<``, ``"``, 
and
+  ``/``) and is less aggressive about replacing existing text.
+
+- Documentation is reflowed in the same way as on hover.
+
+Go-to-definition
+
+
+- Dependent names in templates may be heuristically resolved
+
+- Identifiers in comments may be resolved using other occurrences in the file
+  or in the index.
+
+- Go-to-definition on an ``override`` or ``final`` specifier jumps to the
+  overridden method.
+
+Hover
+^
+
+- Expressions passed as function arguments show parameter name, conversions 
etc.
+
+- Members now include the access specifier in the displayed declaration.
+
+- Classes and fields show memory layout information (size and offset).
+
+- Somewhat improved understanding of formatting in documentation comments.
+
+- Trivial inline getters/setters are implicitly documented as such.
+
+Highlighting
+
+
+- The ``semanticTokens`` protocol from LSP 3.16 is supported.
+  (Only token types are exposed, no modifiers yet).
+
+- The non-standard ``textDocument/semanticHighlighting`` notification is
+  deprecated and will be removed in clangd 12.
+
+- Placing the cursor on a control flow keyword highlights related flow
+  (e.g. ``break`` -> ``for``).
+
+Language support
+
+
+- clangd features now work inside templates on windows.
+  (MSVC-compatible delayed-template-parsing is no longer used).
+
+- Objective-C properties can be targeted and cross-references are indexed.
+
+- Field names in designated initializers (C++20) can be targeted, and code
+  completion works in many cases.
+
+- ``goto`` labels: go-to-defintion, cross-references, and rename all work.
+
+- Concepts (C++20): go-to-definition on concept names, and some limited code
+  completion support for concept members.
+
+System integration
+^^
+
+- The project index is now written to ``$PROJECT/.cache/clangd/index``.
+  ``$PROJECT/.clangd`` is now expected to be a configuration file.
+
+  Old ``$PROJECT/.clangd`` directories can safely be deleted.
+
+  We recommend including both ``.cache/`` and ``.c

[llvm-branch-commits] [clang-tools-extra] a450654 - [clangd] Fix error in release notes

2020-08-10 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-08-10T16:45:11+02:00
New Revision: a450654a52874b094c264e0366c31126c03fdf2d

URL: 
https://github.com/llvm/llvm-project/commit/a450654a52874b094c264e0366c31126c03fdf2d
DIFF: 
https://github.com/llvm/llvm-project/commit/a450654a52874b094c264e0366c31126c03fdf2d.diff

LOG: [clangd] Fix error in release notes

Added: 


Modified: 
clang-tools-extra/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 9f96d6eab38e..83ae2c6605fd 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -207,7 +207,7 @@ System integration
 
   - ``%LocalAppData%\clangd\config.yaml`` on Windows
 
-  - ``~/Library/clangd/config.yaml`` on Mac
+  - ``~/Library/Preferences/clangd/config.yaml`` on Mac
 
   - ``$XDG_CONFIG_HOME/clangd/config.yaml`` or ``~/.config/clangd/config.yaml``
 on others



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] d95db16 - [clangd] Extract common file-caching logic from ConfigProvider.

2020-11-25 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-11-25T12:09:13+01:00
New Revision: d95db1693cbf80b9de58a94b50178fddd62c3e15

URL: 
https://github.com/llvm/llvm-project/commit/d95db1693cbf80b9de58a94b50178fddd62c3e15
DIFF: 
https://github.com/llvm/llvm-project/commit/d95db1693cbf80b9de58a94b50178fddd62c3e15.diff

LOG: [clangd] Extract common file-caching logic from ConfigProvider.

The plan is to use this to use this for .clang-format, .clang-tidy, and
compile_commands.json. (Currently the former two are reparsed every
time, and the latter is cached forever and changes are never seen).

Differential Revision: https://reviews.llvm.org/D88172

Added: 
clang-tools-extra/clangd/support/FileCache.cpp
clang-tools-extra/clangd/support/FileCache.h
clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp

Modified: 
clang-tools-extra/clangd/ConfigProvider.cpp
clang-tools-extra/clangd/ConfigProvider.h
clang-tools-extra/clangd/support/CMakeLists.txt
clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ConfigProvider.cpp 
b/clang-tools-extra/clangd/ConfigProvider.cpp
index 5a00ec5048c0..e020ec04d1d2 100644
--- a/clang-tools-extra/clangd/ConfigProvider.cpp
+++ b/clang-tools-extra/clangd/ConfigProvider.cpp
@@ -9,6 +9,7 @@
 #include "ConfigProvider.h"
 #include "Config.h"
 #include "ConfigFragment.h"
+#include "support/FileCache.h"
 #include "support/ThreadsafeFS.h"
 #include "support/Trace.h"
 #include "llvm/ADT/ScopeExit.h"
@@ -24,89 +25,28 @@ namespace clangd {
 namespace config {
 
 // Threadsafe cache around reading a YAML config file from disk.
-class FileConfigCache {
-  std::mutex Mu;
-  std::chrono::steady_clock::time_point ValidTime = {};
-  llvm::SmallVector CachedValue;
-  llvm::sys::TimePoint<> MTime = {};
-  unsigned Size = -1;
-
-  // Called once we are sure we want to read the file.
-  // REQUIRES: Cache keys are set. Mutex must be held.
-  void fillCacheFromDisk(llvm::vfs::FileSystem &FS, DiagnosticCallback DC) {
-CachedValue.clear();
-
-auto Buf = FS.getBufferForFile(Path);
-// If we failed to read (but stat succeeded), don't cache failure.
-if (!Buf) {
-  Size = -1;
-  MTime = {};
-  return;
-}
-
-// If file changed between stat and open, we don't know its mtime.
-// For simplicity, don't cache the value in this case (use a bad key).
-if (Buf->get()->getBufferSize() != Size) {
-  Size = -1;
-  MTime = {};
-}
-
-// Finally parse and compile the actual fragments.
-for (auto &Fragment :
- Fragment::parseYAML(Buf->get()->getBuffer(), Path, DC)) {
-  Fragment.Source.Directory = Directory;
-  CachedValue.push_back(std::move(Fragment).compile(DC));
-}
-  }
-
-public:
-  // Must be set before the cache is used. Not a constructor param to allow
-  // computing ancestor-relative paths to be deferred.
-  std::string Path;
-  // Directory associated with this fragment.
+class FileConfigCache : public FileCache {
+  mutable llvm::SmallVector CachedValue;
   std::string Directory;
 
-  // Retrieves up-to-date config fragments from disk.
-  // A cached result may be reused if the mtime and size are unchanged.
-  // (But several concurrent read()s can miss the cache after a single change).
-  // Future performance ideas:
-  // - allow caches to be reused based on short elapsed walltime
-  // - allow latency-sensitive operations to skip revalidating the cache
-  void read(const ThreadsafeFS &TFS, DiagnosticCallback DC,
-llvm::Optional FreshTime,
-std::vector &Out) {
-std::lock_guard Lock(Mu);
-// We're going to update the cache and return whatever's in it.
-auto Return = llvm::make_scope_exit(
-[&] { llvm::copy(CachedValue, std::back_inserter(Out)); });
-
-// Return any sufficiently recent result without doing any further work.
-if (FreshTime && ValidTime >= FreshTime)
-  return;
-
-// Ensure we bump the ValidTime at the end to allow for reuse.
-auto MarkTime = llvm::make_scope_exit(
-[&] { ValidTime = std::chrono::steady_clock::now(); });
-
-// Stat is cheaper than opening the file, it's usually unchanged.
-assert(llvm::sys::path::is_absolute(Path));
-auto FS = TFS.view(/*CWD=*/llvm::None);
-auto Stat = FS->status(Path);
-// If there's no file, the result is empty. Ensure we have an invalid key.
-if (!Stat || !Stat->isRegularFile()) {
-  MTime = {};
-  Size = -1;
-  CachedValue.clear();
-  return;
-}
-// If the modified-time and size match, assume the content does too.
-if (Size == Stat->getSize() && MTime == Stat->getLastModificationTime())
-  return;
-
-// OK, the file has actually changed. Update cache key, compute new value.
-Size = Stat->getSize();
-MTime = Stat->getLastModificationTime();
-fillCacheFromDisk(*FS, DC);
+public:
+  Fil

[llvm-branch-commits] [clang-tools-extra] a38d13e - [clangd] Use TimePoint<> instead of system_clock::time_point, it does matter after all.

2020-11-25 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-11-25T12:49:24+01:00
New Revision: a38d13ed3635bfdd35226e8d8d0661a42bcd35c6

URL: 
https://github.com/llvm/llvm-project/commit/a38d13ed3635bfdd35226e8d8d0661a42bcd35c6
DIFF: 
https://github.com/llvm/llvm-project/commit/a38d13ed3635bfdd35226e8d8d0661a42bcd35c6.diff

LOG: [clangd] Use TimePoint<> instead of system_clock::time_point, it does 
matter after all.

Added: 


Modified: 
clang-tools-extra/clangd/support/FileCache.h

Removed: 




diff  --git a/clang-tools-extra/clangd/support/FileCache.h 
b/clang-tools-extra/clangd/support/FileCache.h
index 75782e9ae021..ffc5deb7442b 100644
--- a/clang-tools-extra/clangd/support/FileCache.h
+++ b/clang-tools-extra/clangd/support/FileCache.h
@@ -71,7 +71,7 @@ class FileCache {
   // Time when the cache was known valid (reflected disk state).
   mutable std::chrono::steady_clock::time_point ValidTime;
   // Filesystem metadata corresponding to the currently cached data.
-  mutable std::chrono::system_clock::time_point ModifiedTime;
+  mutable llvm::sys::TimePoint<> ModifiedTime;
   mutable uint64_t Size;
 };
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] cbf336a - [clangd] Track deprecation of 'member' semantic token type in LSP.

2020-11-25 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-11-25T21:31:46+01:00
New Revision: cbf336ad76cd619495b213e8364acaccb7a7c0d6

URL: 
https://github.com/llvm/llvm-project/commit/cbf336ad76cd619495b213e8364acaccb7a7c0d6
DIFF: 
https://github.com/llvm/llvm-project/commit/cbf336ad76cd619495b213e8364acaccb7a7c0d6.diff

LOG: [clangd] Track deprecation of 'member' semantic token type in LSP.

Added: 


Modified: 
clang-tools-extra/clangd/SemanticHighlighting.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp 
b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index 1a78e7a8c0da..44d74f387dd1 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -556,12 +556,11 @@ llvm::StringRef toSemanticTokenType(HighlightingKind 
Kind) {
   case HighlightingKind::Function:
 return "function";
   case HighlightingKind::Method:
-return "member";
+return "method";
   case HighlightingKind::StaticMethod:
-// FIXME: better function/member with static modifier?
+// FIXME: better method with static modifier?
 return "function";
   case HighlightingKind::Field:
-// Not "member": https://github.com/clangd/vscode-clangd/issues/105
 return "property";
   case HighlightingKind::Class:
 return "class";



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] f095ac1 - [clangd] Fix use of system-installed GRPC after f726101b6240a6740b3c0926af759da5e7336f8a

2020-11-26 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-11-26T23:08:27+01:00
New Revision: f095ac11a9550530a4a54298debb8b04b36422be

URL: 
https://github.com/llvm/llvm-project/commit/f095ac11a9550530a4a54298debb8b04b36422be
DIFF: 
https://github.com/llvm/llvm-project/commit/f095ac11a9550530a4a54298debb8b04b36422be.diff

LOG: [clangd] Fix use of system-installed GRPC after 
f726101b6240a6740b3c0926af759da5e7336f8a

We need a real target now, and it was only being created if grpc was
built from source or imported from homebrew.

Differential Revision: https://reviews.llvm.org/D92107

Added: 


Modified: 
llvm/cmake/modules/FindGRPC.cmake

Removed: 




diff  --git a/llvm/cmake/modules/FindGRPC.cmake 
b/llvm/cmake/modules/FindGRPC.cmake
index 7031c5f0016a..8fdb3506dff1 100644
--- a/llvm/cmake/modules/FindGRPC.cmake
+++ b/llvm/cmake/modules/FindGRPC.cmake
@@ -40,6 +40,8 @@ else()
   endif()
   # On macOS the libraries are typically installed via Homebrew and are not on
   # the system path.
+  set(GRPC_OPTS "")
+  set(PROTOBUF_OPTS "")
   if (${APPLE})
 find_program(HOMEBREW brew)
 # If Homebrew is not found, the user might have installed libraries
@@ -57,28 +59,22 @@ else()
   # system path.
   if (GRPC_HOMEBREW_RETURN_CODE EQUAL "0")
 include_directories(${GRPC_HOMEBREW_PATH}/include)
-find_library(GRPC_LIBRARY
- grpc++
- PATHS ${GRPC_HOMEBREW_PATH}/lib
- NO_DEFAULT_PATH
- REQUIRED)
-add_library(grpc++ UNKNOWN IMPORTED GLOBAL)
-set_target_properties(grpc++ PROPERTIES
-  IMPORTED_LOCATION ${GRPC_LIBRARY})
+list(APPEND GRPC_OPTS PATHS ${GRPC_HOMEBREW_PATH}/lib NO_DEFAULT_PATH)
   endif()
   if (PROTOBUF_HOMEBREW_RETURN_CODE EQUAL "0")
 include_directories(${PROTOBUF_HOMEBREW_PATH}/include)
-find_library(PROTOBUF_LIBRARY
- protobuf
- PATHS ${PROTOBUF_HOMEBREW_PATH}/lib
- NO_DEFAULT_PATH
- REQUIRED)
-add_library(protobuf UNKNOWN IMPORTED GLOBAL)
-set_target_properties(protobuf PROPERTIES
-  IMPORTED_LOCATION ${PROTOBUF_LIBRARY})
+list(APPEND PROTOBUF_OPTS PATHS ${PROTOBUF_HOMEBREW_PATH}/lib 
NO_DEFAULT_PATH)
   endif()
 endif()
   endif()
+  find_library(GRPC_LIBRARY grpc++ $GRPC_OPTS REQUIRED)
+  add_library(grpc++ UNKNOWN IMPORTED GLOBAL)
+  message(STATUS "Using grpc++: " ${GRPC_LIBRARY})
+  set_target_properties(grpc++ PROPERTIES IMPORTED_LOCATION ${GRPC_LIBRARY})
+  find_library(PROTOBUF_LIBRARY protobuf $PROTOBUF_OPTS REQUIRED)
+  message(STATUS "Using protobuf: " ${PROTOBUF_LIBRARY})
+  add_library(protobuf UNKNOWN IMPORTED GLOBAL)
+  set_target_properties(protobuf PROPERTIES IMPORTED_LOCATION 
${PROTOBUF_LIBRARY})
 endif()
 
 # Proto headers are generated in ${CMAKE_CURRENT_BINARY_DIR}.



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 67d16b6 - [clangd] Cache .clang-tidy files again.

2020-11-29 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-11-29T13:28:53+01:00
New Revision: 67d16b6da4bef1ee174514148854e77151a62605

URL: 
https://github.com/llvm/llvm-project/commit/67d16b6da4bef1ee174514148854e77151a62605
DIFF: 
https://github.com/llvm/llvm-project/commit/67d16b6da4bef1ee174514148854e77151a62605.diff

LOG: [clangd] Cache .clang-tidy files again.

This cache went away in 73fdd998701cce3aa6c4d8d2a73ab97351a0313b

This time, the cache is periodically validated against disk, so config
is still mostly "live".

The per-file cache reuses FileCache, but the tree-of-file-caches is
duplicated from ConfigProvider. .clangd, .clang-tidy, .clang-format, and
compile_commands.json all have this pattern, we should extract it at some point.
TODO for now though.

Differential Revision: https://reviews.llvm.org/D92133

Added: 


Modified: 
clang-tools-extra/clangd/TidyProvider.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/TidyProvider.cpp 
b/clang-tools-extra/clangd/TidyProvider.cpp
index 1fb79f3abbce3..687ae6501d25f 100644
--- a/clang-tools-extra/clangd/TidyProvider.cpp
+++ b/clang-tools-extra/clangd/TidyProvider.cpp
@@ -8,7 +8,9 @@
 
 #include "TidyProvider.h"
 #include "Config.h"
+#include "support/FileCache.h"
 #include "support/Logger.h"
+#include "support/ThreadsafeFS.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
@@ -19,53 +21,115 @@
 
 namespace clang {
 namespace clangd {
+namespace {
 
-static void mergeCheckList(llvm::Optional &Checks,
-   llvm::StringRef List) {
-  if (List.empty())
-return;
-  if (!Checks || Checks->empty()) {
-Checks.emplace(List);
-return;
+// Access to config from a .clang-tidy file, caching IO and parsing.
+class DotClangTidyCache : private FileCache {
+  // We cache and expose shared_ptr to avoid copying the value on every lookup
+  // when we're ultimately just going to pass it to mergeWith.
+  mutable std::shared_ptr Value;
+
+public:
+  DotClangTidyCache(PathRef Path) : FileCache(Path) {}
+
+  std::shared_ptr
+  get(const ThreadsafeFS &TFS,
+  std::chrono::steady_clock::time_point FreshTime) const {
+std::shared_ptr Result;
+read(
+TFS, FreshTime,
+[this](llvm::Optional Data) {
+  Value.reset();
+  if (Data && !Data->empty()) {
+if (auto Parsed = tidy::parseConfiguration(*Data))
+  Value = std::make_shared(
+  std::move(*Parsed));
+else
+  elog("Error parsing clang-tidy configuration in {0}: {1}", 
path(),
+   Parsed.getError().message());
+  }
+},
+[&]() { Result = Value; });
+return Result;
   }
-  *Checks = llvm::join_items(",", *Checks, List);
-}
+};
 
-static llvm::Optional
-tryReadConfigFile(llvm::vfs::FileSystem *FS, llvm::StringRef Directory) {
-  assert(!Directory.empty());
-  // We guaranteed that child directories of Directory exist, so this assert
-  // should hopefully never fail.
-  assert(FS->exists(Directory));
+// Access to combined config from .clang-tidy files governing a source file.
+// Each config file is cached and the caches are shared for affected sources.
+//
+// FIXME: largely duplicates config::Provider::fromAncestorRelativeYAMLFiles.
+// Potentially useful for compile_commands.json too. Extract?
+class DotClangTidyTree {
+  const ThreadsafeFS &FS;
+  std::string RelPath;
+  std::chrono::steady_clock::duration MaxStaleness;
 
-  llvm::SmallString<128> ConfigFile(Directory);
-  llvm::sys::path::append(ConfigFile, ".clang-tidy");
+  mutable std::mutex Mu;
+  // Keys are the ancestor directory, not the actual config path within it.
+  // We only insert into this map, so pointers to values are stable forever.
+  // Mutex guards the map itself, not the values (which are threadsafe).
+  mutable llvm::StringMap Cache;
 
-  llvm::ErrorOr FileStatus = FS->status(ConfigFile);
+public:
+  DotClangTidyTree(const ThreadsafeFS &FS)
+  : FS(FS), RelPath(".clang-tidy"), MaxStaleness(std::chrono::seconds(5)) 
{}
 
-  if (!FileStatus || !FileStatus->isRegularFile())
-return llvm::None;
+  void apply(tidy::ClangTidyOptions &Result, PathRef AbsPath) {
+namespace path = llvm::sys::path;
+assert(path::is_absolute(AbsPath));
+
+// Compute absolute paths to all ancestors (substrings of P.Path).
+// Ensure cache entries for each ancestor exist in the map.
+llvm::StringRef Parent = path::parent_path(AbsPath);
+llvm::SmallVector Caches;
+{
+  std::lock_guard Lock(Mu);
+  for (auto I = path::begin(Parent, path::Style::posix),
+E = path::end(Parent);
+   I != E; ++I) {
+assert(I->end() >= Parent.begin() && I->end() <= Parent.end() &&
+   "Canonical path components should be substrings");
+llvm::StringRef Ancestor(Parent.begin(), I->end() - Parent.begin());

[llvm-branch-commits] [clang-tools-extra] d99da80 - [clangd] Fix path edge-case condition.

2020-11-29 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-11-29T13:40:29+01:00
New Revision: d99da80841cb4d9734db4a48cd49e37b623176bc

URL: 
https://github.com/llvm/llvm-project/commit/d99da80841cb4d9734db4a48cd49e37b623176bc
DIFF: 
https://github.com/llvm/llvm-project/commit/d99da80841cb4d9734db4a48cd49e37b623176bc.diff

LOG: [clangd] Fix path edge-case condition.

Added: 


Modified: 
clang-tools-extra/clangd/ConfigProvider.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ConfigProvider.cpp 
b/clang-tools-extra/clangd/ConfigProvider.cpp
index e020ec04d1d2..8a3991ed1c1e 100644
--- a/clang-tools-extra/clangd/ConfigProvider.cpp
+++ b/clang-tools-extra/clangd/ConfigProvider.cpp
@@ -103,7 +103,7 @@ Provider::fromAncestorRelativeYAMLFiles(llvm::StringRef 
RelPath,
I != E; ++I) {
 // Avoid weird non-substring cases like phantom "." components.
 // In practice, Component is a substring for all "normal" ancestors.
-if (I->end() < Parent.begin() && I->end() > Parent.end())
+if (I->end() < Parent.begin() || I->end() > Parent.end())
   continue;
 Ancestors.emplace_back(Parent.begin(), I->end() - Parent.begin());
   }



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] 650e04e - [Tooling] JSONCompilationDatabase::loadFromBuffer retains the buffer, copy it.

2020-12-04 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-04T21:54:55+01:00
New Revision: 650e04e179c9d355cd6d8f9a108d60c7969d24ca

URL: 
https://github.com/llvm/llvm-project/commit/650e04e179c9d355cd6d8f9a108d60c7969d24ca
DIFF: 
https://github.com/llvm/llvm-project/commit/650e04e179c9d355cd6d8f9a108d60c7969d24ca.diff

LOG: [Tooling] JSONCompilationDatabase::loadFromBuffer retains the buffer, copy 
it.

This function doesn't seem to be used in-tree outside tests.
However clangd wants to use it soon, and having the CDB be self-contained seems
reasonable.

Differential Revision: https://reviews.llvm.org/D92646

Added: 


Modified: 
clang/lib/Tooling/JSONCompilationDatabase.cpp
clang/unittests/Tooling/CompilationDatabaseTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp 
b/clang/lib/Tooling/JSONCompilationDatabase.cpp
index 4aa16853ce45..2d8847a7a327 100644
--- a/clang/lib/Tooling/JSONCompilationDatabase.cpp
+++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp
@@ -217,7 +217,7 @@ JSONCompilationDatabase::loadFromBuffer(StringRef 
DatabaseString,
 std::string &ErrorMessage,
 JSONCommandLineSyntax Syntax) {
   std::unique_ptr DatabaseBuffer(
-  llvm::MemoryBuffer::getMemBuffer(DatabaseString));
+  llvm::MemoryBuffer::getMemBufferCopy(DatabaseString));
   std::unique_ptr Database(
   new JSONCompilationDatabase(std::move(DatabaseBuffer), Syntax));
   if (!Database->parse(ErrorMessage))

diff  --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp 
b/clang/unittests/Tooling/CompilationDatabaseTest.cpp
index 9e2342894f71..168a1d6f0fb0 100644
--- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -172,13 +172,15 @@ TEST(JSONCompilationDatabase, GetAllCompileCommands) {
 }
 
 static CompileCommand findCompileArgsInJsonDatabase(StringRef FileName,
-StringRef JSONDatabase,
+std::string JSONDatabase,
 std::string &ErrorMessage) 
{
   std::unique_ptr Database(
   JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage,
   JSONCommandLineSyntax::Gnu));
   if (!Database)
 return CompileCommand();
+  // Overwrite the string to verify we're not reading from it later.
+  JSONDatabase.assign(JSONDatabase.size(), '*');
   std::vector Commands = 
Database->getCompileCommands(FileName);
   EXPECT_LE(Commands.size(), 1u);
   if (Commands.empty())



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] fed9af2 - [clangd] Publish config file errors over LSP

2020-12-07 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-07T11:07:32+01:00
New Revision: fed9af29c2b5f289744254390c7372e8871e45e5

URL: 
https://github.com/llvm/llvm-project/commit/fed9af29c2b5f289744254390c7372e8871e45e5
DIFF: 
https://github.com/llvm/llvm-project/commit/fed9af29c2b5f289744254390c7372e8871e45e5.diff

LOG: [clangd] Publish config file errors over LSP

We don't act as a language server for these files (e.g. don't get open/close
notifications for them), but just blindly publish diagnostics for them.

This works reasonably well in coc.nvim and vscode: they show up in the
workspace diagnostic list and when you open the file.
The only update after the file is reparsed, not as you type which is a bit
janky, but seems a lot better than nothing.

Fixes https://github.com/clangd/clangd/issues/614

Differential Revision: https://reviews.llvm.org/D92704

Added: 
clang-tools-extra/clangd/test/config.test

Modified: 
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/ConfigProvider.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/Diagnostics.cpp
clang-tools-extra/clangd/Diagnostics.h
clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp
clang-tools-extra/clangd/unittests/ConfigTesting.h
clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index aa19a9485e17..8b0d0591abe7 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -139,7 +139,7 @@ ClangdServer::Options::operator TUScheduler::Options() 
const {
 ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
const ThreadsafeFS &TFS, const Options &Opts,
Callbacks *Callbacks)
-: ConfigProvider(Opts.ConfigProvider), TFS(TFS),
+: ConfigProvider(Opts.ConfigProvider), TFS(TFS), 
ServerCallbacks(Callbacks),
   DynamicIdx(Opts.BuildDynamicSymbolIndex
  ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex,
  Opts.CollectMainFileRefs)
@@ -829,16 +829,44 @@ Context ClangdServer::createProcessingContext(PathRef 
File) const {
 Params.Path = PosixPath.str();
   }
 
-  auto DiagnosticHandler = [](const llvm::SMDiagnostic &Diag) {
-if (Diag.getKind() == llvm::SourceMgr::DK_Error) {
-  elog("config error at {0}:{1}:{2}: {3}", Diag.getFilename(),
-   Diag.getLineNo(), Diag.getColumnNo(), Diag.getMessage());
-} else {
-  log("config warning at {0}:{1}:{2}: {3}", Diag.getFilename(),
-  Diag.getLineNo(), Diag.getColumnNo(), Diag.getMessage());
+  llvm::StringMap> ReportableDiagnostics;
+  auto ConfigDiagnosticHandler = [&](const llvm::SMDiagnostic &D) {
+// Ensure we create the map entry even for note diagnostics we don't 
report.
+// This means that when the file is parsed with no warnings, we'll
+// publish an empty set of diagnostics, clearing any the client has.
+auto *Reportable = D.getFilename().empty()
+   ? nullptr
+   : &ReportableDiagnostics[D.getFilename()];
+switch (D.getKind()) {
+case llvm::SourceMgr::DK_Error:
+  elog("config error at {0}:{1}:{2}: {3}", D.getFilename(), D.getLineNo(),
+   D.getColumnNo(), D.getMessage());
+  if (Reportable)
+Reportable->push_back(toDiag(D, Diag::ClangdConfig));
+  break;
+case llvm::SourceMgr::DK_Warning:
+  log("config warning at {0}:{1}:{2}: {3}", D.getFilename(), D.getLineNo(),
+  D.getColumnNo(), D.getMessage());
+  if (Reportable)
+Reportable->push_back(toDiag(D, Diag::ClangdConfig));
+  break;
+case llvm::SourceMgr::DK_Note:
+case llvm::SourceMgr::DK_Remark:
+  vlog("config note at {0}:{1}:{2}: {3}", D.getFilename(), D.getLineNo(),
+   D.getColumnNo(), D.getMessage());
+  break;
 }
   };
-  Config C = ConfigProvider->getConfig(Params, DiagnosticHandler);
+  Config C = ConfigProvider->getConfig(Params, ConfigDiagnosticHandler);
+  // Blindly publish diagnostics for the (unopened) parsed config files.
+  // We must avoid reporting diagnostics for *the same file* concurrently.
+  // Source file diags are published elsewhere, but those are 
diff erent files.
+  if (!ReportableDiagnostics.empty()) {
+std::lock_guard Lock(ConfigDiagnosticsMu);
+for (auto &Entry : ReportableDiagnostics)
+  ServerCallbacks->onDiagnosticsReady(Entry.first(), /*Version=*/"",
+  std::move(Entry.second));
+  }
   return Context::current().derive(Config::Key, std::move(C));
 }
 

diff  --git a/clang-tools-extra/clangd/ClangdServer.h 
b/clang-tools-extra/clangd/ClangdServer.h
index 35ba4686cc9a..ff2fc8578103 100644
--- a/clang-tool

[llvm-branch-commits] [clang-tools-extra] f135726 - [clangd] Temporarily test that uncovered broken behavior on windows

2020-12-07 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-07T12:34:17+01:00
New Revision: f1357264b8e3070bef5bb4ff35ececa4d6c76108

URL: 
https://github.com/llvm/llvm-project/commit/f1357264b8e3070bef5bb4ff35ececa4d6c76108
DIFF: 
https://github.com/llvm/llvm-project/commit/f1357264b8e3070bef5bb4ff35ececa4d6c76108.diff

LOG: [clangd] Temporarily test that uncovered broken behavior on windows

Added: 


Modified: 
clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp 
b/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp
index b2217bbc55da..4e44af6fad58 100644
--- a/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp
@@ -144,8 +144,11 @@ TEST(ProviderTest, FromAncestorRelativeYAMLFiles) {
   Cfg = P->getConfig(ABCParams, Diags.callback());
   EXPECT_THAT(Diags.Diagnostics,
   ElementsAre(DiagMessage("Unknown CompileFlags key Unknown")));
+#ifdef LLVM_ON_UNIX
+  // FIXME: fails on windows: paths have mixed slashes like C:\a/b\c.yaml
   EXPECT_THAT(Diags.Files,
   ElementsAre(testPath("a/foo.yaml"), testPath("a/b/c/foo.yaml")));
+#endif
   EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("foo", "bar", "baz"));
   Diags.clear();
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 2542ef8 - [clangd] Fix windows slashes in project config diagnostics

2020-12-07 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-07T12:54:38+01:00
New Revision: 2542ef83ed7c5a10f8b394ec8e7764558dc71d32

URL: 
https://github.com/llvm/llvm-project/commit/2542ef83ed7c5a10f8b394ec8e7764558dc71d32
DIFF: 
https://github.com/llvm/llvm-project/commit/2542ef83ed7c5a10f8b394ec8e7764558dc71d32.diff

LOG: [clangd] Fix windows slashes in project config diagnostics

Added: 


Modified: 
clang-tools-extra/clangd/ConfigProvider.cpp
clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/ConfigProvider.cpp 
b/clang-tools-extra/clangd/ConfigProvider.cpp
index 8a3991ed1c1e..0933e7e2c283 100644
--- a/clang-tools-extra/clangd/ConfigProvider.cpp
+++ b/clang-tools-extra/clangd/ConfigProvider.cpp
@@ -83,7 +83,7 @@ Provider::fromAncestorRelativeYAMLFiles(llvm::StringRef 
RelPath,
 const ThreadsafeFS &FS;
 
 mutable std::mutex Mu;
-// Keys are the ancestor directory, not the actual config path within it.
+// Keys are the (posix-style) ancestor directory, not the config within it.
 // We only insert into this map, so pointers to values are stable forever.
 // Mutex guards the map itself, not the values (which are threadsafe).
 mutable llvm::StringMap Cache;
@@ -117,6 +117,8 @@ Provider::fromAncestorRelativeYAMLFiles(llvm::StringRef 
RelPath,
   if (It == Cache.end()) {
 llvm::SmallString<256> ConfigPath = Ancestor;
 path::append(ConfigPath, RelPath);
+// Use native slashes for reading the file, affects diagnostics.
+llvm::sys::path::native(ConfigPath);
 It = Cache.try_emplace(Ancestor, ConfigPath.str(), Ancestor).first;
   }
   Caches.push_back(&It->second);

diff  --git a/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp 
b/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp
index 4e44af6fad58..9c45266d1a83 100644
--- a/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigProviderTests.cpp
@@ -144,11 +144,9 @@ TEST(ProviderTest, FromAncestorRelativeYAMLFiles) {
   Cfg = P->getConfig(ABCParams, Diags.callback());
   EXPECT_THAT(Diags.Diagnostics,
   ElementsAre(DiagMessage("Unknown CompileFlags key Unknown")));
-#ifdef LLVM_ON_UNIX
   // FIXME: fails on windows: paths have mixed slashes like C:\a/b\c.yaml
   EXPECT_THAT(Diags.Files,
   ElementsAre(testPath("a/foo.yaml"), testPath("a/b/c/foo.yaml")));
-#endif
   EXPECT_THAT(getAddedArgs(Cfg), ElementsAre("foo", "bar", "baz"));
   Diags.clear();
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] a1cb9cb - Add ability to load a FixedCompilationDatabase from a buffer.

2020-12-07 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-07T13:07:10+01:00
New Revision: a1cb9cbf5c4939e78a6c3b3677cf8e3dbdf51932

URL: 
https://github.com/llvm/llvm-project/commit/a1cb9cbf5c4939e78a6c3b3677cf8e3dbdf51932
DIFF: 
https://github.com/llvm/llvm-project/commit/a1cb9cbf5c4939e78a6c3b3677cf8e3dbdf51932.diff

LOG: Add ability to load a FixedCompilationDatabase from a buffer.

Previously, loading one from a file meant allowing the library to do the IO.
Clangd would prefer to do such IO itself (e.g. to allow caching).

Differential Revision: https://reviews.llvm.org/D92640

Added: 


Modified: 
clang/include/clang/Tooling/CompilationDatabase.h
clang/lib/Tooling/CompilationDatabase.cpp
clang/unittests/Tooling/CompilationDatabaseTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/CompilationDatabase.h 
b/clang/include/clang/Tooling/CompilationDatabase.h
index b28a8a6d6e51..cbd57e9609aa 100644
--- a/clang/include/clang/Tooling/CompilationDatabase.h
+++ b/clang/include/clang/Tooling/CompilationDatabase.h
@@ -184,11 +184,16 @@ class FixedCompilationDatabase : public 
CompilationDatabase {
   int &Argc, const char *const *Argv, std::string &ErrorMsg,
   Twine Directory = ".");
 
-  /// Reads flags from the given file, one-per line.
+  /// Reads flags from the given file, one-per-line.
   /// Returns nullptr and sets ErrorMessage if we can't read the file.
   static std::unique_ptr
   loadFromFile(StringRef Path, std::string &ErrorMsg);
 
+  /// Reads flags from the given buffer, one-per-line.
+  /// Directory is the command CWD, typically the parent of compile_flags.txt.
+  static std::unique_ptr
+  loadFromBuffer(StringRef Directory, StringRef Data, std::string &ErrorMsg);
+
   /// Constructs a compilation data base from a specified directory
   /// and command line.
   FixedCompilationDatabase(Twine Directory, ArrayRef CommandLine);

diff  --git a/clang/lib/Tooling/CompilationDatabase.cpp 
b/clang/lib/Tooling/CompilationDatabase.cpp
index 79bb8c0ce09a..d339fd044c02 100644
--- a/clang/lib/Tooling/CompilationDatabase.cpp
+++ b/clang/lib/Tooling/CompilationDatabase.cpp
@@ -348,16 +348,24 @@ FixedCompilationDatabase::loadFromFile(StringRef Path, 
std::string &ErrorMsg) {
 ErrorMsg = "Error while opening fixed database: " + Result.message();
 return nullptr;
   }
+  return loadFromBuffer(llvm::sys::path::parent_path(Path),
+(*File)->getBuffer(), ErrorMsg);
+}
+
+std::unique_ptr
+FixedCompilationDatabase::loadFromBuffer(StringRef Directory, StringRef Data,
+ std::string &ErrorMsg) {
+  ErrorMsg.clear();
   std::vector Args;
-  for (llvm::StringRef Line :
-   llvm::make_range(llvm::line_iterator(**File), llvm::line_iterator())) {
+  StringRef Line;
+  while (!Data.empty()) {
+std::tie(Line, Data) = Data.split('\n');
 // Stray whitespace is almost certainly unintended.
 Line = Line.trim();
 if (!Line.empty())
   Args.push_back(Line.str());
   }
-  return std::make_unique(
-  llvm::sys::path::parent_path(Path), std::move(Args));
+  return std::make_unique(Directory, 
std::move(Args));
 }
 
 FixedCompilationDatabase::

diff  --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp 
b/clang/unittests/Tooling/CompilationDatabaseTest.cpp
index 168a1d6f0fb0..a3ea899e572e 100644
--- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -543,6 +543,27 @@ TEST(FixedCompilationDatabase, GetAllCompileCommands) {
   EXPECT_EQ(0ul, Database.getAllCompileCommands().size());
 }
 
+TEST(FixedCompilationDatabase, FromBuffer) {
+  const char *Data = R"(
+
+ -DFOO=BAR
+
+--baz
+
+  )";
+  std::string ErrorMsg;
+  auto CDB =
+  FixedCompilationDatabase::loadFromBuffer("/cdb/dir", Data, ErrorMsg);
+
+  std::vector Result = CDB->getCompileCommands("/foo/bar.cc");
+  ASSERT_EQ(1ul, Result.size());
+  EXPECT_EQ("/cdb/dir", Result.front().Directory);
+  EXPECT_EQ("/foo/bar.cc", Result.front().Filename);
+  EXPECT_THAT(
+  Result.front().CommandLine,
+  ElementsAre(EndsWith("clang-tool"), "-DFOO=BAR", "--baz", 
"/foo/bar.cc"));
+}
+
 TEST(ParseFixedCompilationDatabase, ReturnsNullOnEmptyArgumentList) {
   int Argc = 0;
   std::string ErrorMsg;



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 634a377 - [clangd] Extract per-dir CDB cache to its own threadsafe class. NFC

2020-12-09 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-09T17:40:12+01:00
New Revision: 634a377bd8cbaa515a58295cfd85dcb6a21381c1

URL: 
https://github.com/llvm/llvm-project/commit/634a377bd8cbaa515a58295cfd85dcb6a21381c1
DIFF: 
https://github.com/llvm/llvm-project/commit/634a377bd8cbaa515a58295cfd85dcb6a21381c1.diff

LOG: [clangd] Extract per-dir CDB cache to its own threadsafe class. NFC

This is a step towards making compile_commands.json reloadable.

The idea is:
 - in addition to rare CDB loads we're soon going to have somewhat-rare CDB
   reloads and fairly-common stat() of files to validate the CDB
 - so stop doing all our work under a big global lock, instead using it to
   acquire per-directory structures with their own locks
 - each directory can be refreshed from disk every N seconds, like filecache
 - avoid locking these at all in the most common case: directory has no CDB

Differential Revision: https://reviews.llvm.org/D92381

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index 23e8c9fe716d0..f867920c9d1fc 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -16,11 +16,13 @@
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
+#include 
 #include 
 #include 
 #include 
@@ -58,10 +60,117 @@ GlobalCompilationDatabase::getFallbackCommand(PathRef 
File) const {
   return Cmd;
 }
 
+// Loads and caches the CDB from a single directory.
+//
+// This class is threadsafe, which is to say we have independent locks for each
+// directory we're searching for a CDB.
+// Loading is deferred until first access.
+//
+// The DirectoryBasedCDB keeps a map from path => DirectoryCache.
+// Typical usage is to:
+//  - 1) determine all the paths that might be searched
+//  - 2) acquire the map lock and get-or-create all the DirectoryCache entries
+//  - 3) release the map lock and query the caches as desired
+//
+// FIXME: this should revalidate the cache sometimes
+// FIXME: IO should go through a VFS
+class DirectoryBasedGlobalCompilationDatabase::DirectoryCache {
+  // Absolute canonical path that we're the cache for. (Not case-folded).
+  const std::string Path;
+
+  // True if we've looked for a CDB here and found none.
+  // (This makes it possible for get() to return without taking a lock)
+  // FIXME: this should have an expiry time instead of lasting forever.
+  std::atomic FinalizedNoCDB = {false};
+
+  // Guards following cache state.
+  std::mutex Mu;
+  // Has cache been filled from disk? FIXME: this should be an expiry time.
+  bool CachePopulated = false;
+  // Whether a new CDB has been loaded but not broadcast yet.
+  bool NeedsBroadcast = false;
+  // Last loaded CDB, meaningful if CachePopulated is set.
+  // shared_ptr so we can overwrite this when callers are still using the CDB.
+  std::shared_ptr CDB;
+
+public:
+  DirectoryCache(llvm::StringRef Path) : Path(Path) {
+assert(llvm::sys::path::is_absolute(Path));
+  }
+
+  // Get the CDB associated with this directory.
+  // ShouldBroadcast:
+  //  - as input, signals whether the caller is willing to broadcast a
+  //newly-discovered CDB. (e.g. to trigger background indexing)
+  //  - as output, signals whether the caller should do so.
+  // (If a new CDB is discovered and ShouldBroadcast is false, we mark the
+  // CDB as needing broadcast, and broadcast it next time we can).
+  std::shared_ptr
+  get(bool &ShouldBroadcast) {
+// Fast path for common case without taking lock.
+if (FinalizedNoCDB.load()) {
+  ShouldBroadcast = false;
+  return nullptr;
+}
+std::lock_guard Lock(Mu);
+auto RequestBroadcast = llvm::make_scope_exit([&, OldCDB(CDB.get())] {
+  // If we loaded a new CDB, it should be broadcast at some point.
+  if (CDB != nullptr && CDB.get() != OldCDB)
+NeedsBroadcast = true;
+  else if (CDB == nullptr) // nothing to broadcast anymore!
+NeedsBroadcast = false;
+  // If we have something to broadcast, then do so iff allowed.
+  if (!ShouldBroadcast)
+return;
+  ShouldBroadcast = NeedsBroadcast;
+  NeedsBroadcast = false;
+});
+
+// For now, we never actually attempt to revalidate a populated cache.
+if (CachePopulated)
+  return CDB;
+assert(CDB == nullptr);
+
+load();
+CachePopulated = true;
+
+if (!CDB)
+  FinalizedNoCDB.store(true);
+return CDB;
+  }
+
+  llvm::StringRef path() const {

[llvm-branch-commits] [clang-tools-extra] 8a4390d - Reland [clangd] Extract per-dir CDB cache to its own threadsafe class. NFC

2020-12-11 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-11T17:34:53+01:00
New Revision: 8a4390dc4768fcd929a7231717980ccb28f124f7

URL: 
https://github.com/llvm/llvm-project/commit/8a4390dc4768fcd929a7231717980ccb28f124f7
DIFF: 
https://github.com/llvm/llvm-project/commit/8a4390dc4768fcd929a7231717980ccb28f124f7.diff

LOG: Reland [clangd] Extract per-dir CDB cache to its own threadsafe class. NFC

This reverts commit de4f5519015cc97f28718d90cc6dac73c0a15161.

More debug output to try to pin down an impossible condition.

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index 23e8c9fe716d..a50666ea8ccb 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -16,11 +16,13 @@
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
+#include 
 #include 
 #include 
 #include 
@@ -58,10 +60,117 @@ GlobalCompilationDatabase::getFallbackCommand(PathRef 
File) const {
   return Cmd;
 }
 
+// Loads and caches the CDB from a single directory.
+//
+// This class is threadsafe, which is to say we have independent locks for each
+// directory we're searching for a CDB.
+// Loading is deferred until first access.
+//
+// The DirectoryBasedCDB keeps a map from path => DirectoryCache.
+// Typical usage is to:
+//  - 1) determine all the paths that might be searched
+//  - 2) acquire the map lock and get-or-create all the DirectoryCache entries
+//  - 3) release the map lock and query the caches as desired
+//
+// FIXME: this should revalidate the cache sometimes
+// FIXME: IO should go through a VFS
+class DirectoryBasedGlobalCompilationDatabase::DirectoryCache {
+  // Absolute canonical path that we're the cache for. (Not case-folded).
+  const std::string Path;
+
+  // True if we've looked for a CDB here and found none.
+  // (This makes it possible for get() to return without taking a lock)
+  // FIXME: this should have an expiry time instead of lasting forever.
+  std::atomic FinalizedNoCDB = {false};
+
+  // Guards following cache state.
+  std::mutex Mu;
+  // Has cache been filled from disk? FIXME: this should be an expiry time.
+  bool CachePopulated = false;
+  // Whether a new CDB has been loaded but not broadcast yet.
+  bool NeedsBroadcast = false;
+  // Last loaded CDB, meaningful if CachePopulated is set.
+  // shared_ptr so we can overwrite this when callers are still using the CDB.
+  std::shared_ptr CDB;
+
+public:
+  DirectoryCache(llvm::StringRef Path) : Path(Path) {
+assert(llvm::sys::path::is_absolute(Path));
+  }
+
+  // Get the CDB associated with this directory.
+  // ShouldBroadcast:
+  //  - as input, signals whether the caller is willing to broadcast a
+  //newly-discovered CDB. (e.g. to trigger background indexing)
+  //  - as output, signals whether the caller should do so.
+  // (If a new CDB is discovered and ShouldBroadcast is false, we mark the
+  // CDB as needing broadcast, and broadcast it next time we can).
+  std::shared_ptr
+  get(bool &ShouldBroadcast) {
+// Fast path for common case without taking lock.
+if (FinalizedNoCDB.load()) {
+  ShouldBroadcast = false;
+  return nullptr;
+}
+std::lock_guard Lock(Mu);
+auto RequestBroadcast = llvm::make_scope_exit([&, OldCDB(CDB.get())] {
+  // If we loaded a new CDB, it should be broadcast at some point.
+  if (CDB != nullptr && CDB.get() != OldCDB)
+NeedsBroadcast = true;
+  else if (CDB == nullptr) // nothing to broadcast anymore!
+NeedsBroadcast = false;
+  // If we have something to broadcast, then do so iff allowed.
+  if (!ShouldBroadcast)
+return;
+  ShouldBroadcast = NeedsBroadcast;
+  NeedsBroadcast = false;
+});
+
+// For now, we never actually attempt to revalidate a populated cache.
+if (CachePopulated)
+  return CDB;
+assert(CDB == nullptr);
+
+load();
+CachePopulated = true;
+
+if (!CDB)
+  FinalizedNoCDB.store(true);
+return CDB;
+  }
+
+  llvm::StringRef path() const { return Path; }
+
+private:
+  // Updates `CDB` from disk state.
+  void load() {
+std::string Error; // ignored, because it's often "didn't find anything".
+CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
+if (!CDB) {
+  // Fallback: check for $src/build, the conventional CMake build root.
+  // Probe existence first to avoid each plugin doing IO if it doesn't
+  // exist.
+  ll

[llvm-branch-commits] [clang-tools-extra] 4d956af - Revert [clangd] Extract per-dir CDB cache to its own threadsafe class. NFC

2020-12-11 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-12-11T17:35:50+01:00
New Revision: 4d956af594c5adc9d566d1846d86dd89c70c9c0b

URL: 
https://github.com/llvm/llvm-project/commit/4d956af594c5adc9d566d1846d86dd89c70c9c0b
DIFF: 
https://github.com/llvm/llvm-project/commit/4d956af594c5adc9d566d1846d86dd89c70c9c0b.diff

LOG: Revert [clangd] Extract per-dir CDB cache to its own threadsafe class. NFC

This reverts commit 8a4390dc4768fcd929a7231717980ccb28f124f7.

(The reland did not have the bugfix, just trying to get more details
from the buildbots)

Added: 


Modified: 
clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
clang-tools-extra/clangd/GlobalCompilationDatabase.h

Removed: 




diff  --git a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp 
b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
index a50666ea8ccb..23e8c9fe716d 100644
--- a/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
+++ b/clang-tools-extra/clangd/GlobalCompilationDatabase.cpp
@@ -16,13 +16,11 @@
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-#include 
 #include 
 #include 
 #include 
@@ -60,117 +58,10 @@ GlobalCompilationDatabase::getFallbackCommand(PathRef 
File) const {
   return Cmd;
 }
 
-// Loads and caches the CDB from a single directory.
-//
-// This class is threadsafe, which is to say we have independent locks for each
-// directory we're searching for a CDB.
-// Loading is deferred until first access.
-//
-// The DirectoryBasedCDB keeps a map from path => DirectoryCache.
-// Typical usage is to:
-//  - 1) determine all the paths that might be searched
-//  - 2) acquire the map lock and get-or-create all the DirectoryCache entries
-//  - 3) release the map lock and query the caches as desired
-//
-// FIXME: this should revalidate the cache sometimes
-// FIXME: IO should go through a VFS
-class DirectoryBasedGlobalCompilationDatabase::DirectoryCache {
-  // Absolute canonical path that we're the cache for. (Not case-folded).
-  const std::string Path;
-
-  // True if we've looked for a CDB here and found none.
-  // (This makes it possible for get() to return without taking a lock)
-  // FIXME: this should have an expiry time instead of lasting forever.
-  std::atomic FinalizedNoCDB = {false};
-
-  // Guards following cache state.
-  std::mutex Mu;
-  // Has cache been filled from disk? FIXME: this should be an expiry time.
-  bool CachePopulated = false;
-  // Whether a new CDB has been loaded but not broadcast yet.
-  bool NeedsBroadcast = false;
-  // Last loaded CDB, meaningful if CachePopulated is set.
-  // shared_ptr so we can overwrite this when callers are still using the CDB.
-  std::shared_ptr CDB;
-
-public:
-  DirectoryCache(llvm::StringRef Path) : Path(Path) {
-assert(llvm::sys::path::is_absolute(Path));
-  }
-
-  // Get the CDB associated with this directory.
-  // ShouldBroadcast:
-  //  - as input, signals whether the caller is willing to broadcast a
-  //newly-discovered CDB. (e.g. to trigger background indexing)
-  //  - as output, signals whether the caller should do so.
-  // (If a new CDB is discovered and ShouldBroadcast is false, we mark the
-  // CDB as needing broadcast, and broadcast it next time we can).
-  std::shared_ptr
-  get(bool &ShouldBroadcast) {
-// Fast path for common case without taking lock.
-if (FinalizedNoCDB.load()) {
-  ShouldBroadcast = false;
-  return nullptr;
-}
-std::lock_guard Lock(Mu);
-auto RequestBroadcast = llvm::make_scope_exit([&, OldCDB(CDB.get())] {
-  // If we loaded a new CDB, it should be broadcast at some point.
-  if (CDB != nullptr && CDB.get() != OldCDB)
-NeedsBroadcast = true;
-  else if (CDB == nullptr) // nothing to broadcast anymore!
-NeedsBroadcast = false;
-  // If we have something to broadcast, then do so iff allowed.
-  if (!ShouldBroadcast)
-return;
-  ShouldBroadcast = NeedsBroadcast;
-  NeedsBroadcast = false;
-});
-
-// For now, we never actually attempt to revalidate a populated cache.
-if (CachePopulated)
-  return CDB;
-assert(CDB == nullptr);
-
-load();
-CachePopulated = true;
-
-if (!CDB)
-  FinalizedNoCDB.store(true);
-return CDB;
-  }
-
-  llvm::StringRef path() const { return Path; }
-
-private:
-  // Updates `CDB` from disk state.
-  void load() {
-std::string Error; // ignored, because it's often "didn't find anything".
-CDB = tooling::CompilationDatabase::loadFromDirectory(Path, Error);
-if (!CDB) {
-  // Fallback: check for $src/build, the conventional CMake build root.
-  // Probe existence first to avoid each plugin doing IO if it doesn't

[llvm-branch-commits] [clang-tools-extra-branch] r370024 - [clangd] Release notes for 9.x

2019-08-27 Thread Sam McCall via llvm-branch-commits
Author: sammccall
Date: Tue Aug 27 00:01:25 2019
New Revision: 370024

URL: http://llvm.org/viewvc/llvm-project?rev=370024&view=rev
Log:
[clangd] Release notes for 9.x


Modified:
clang-tools-extra/branches/release_90/docs/ReleaseNotes.rst

Modified: clang-tools-extra/branches/release_90/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/branches/release_90/docs/ReleaseNotes.rst?rev=370024&r1=370023&r2=370024&view=diff
==
--- clang-tools-extra/branches/release_90/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/branches/release_90/docs/ReleaseNotes.rst Tue Aug 27 
00:01:25 2019
@@ -47,7 +47,98 @@ Major New Features
 Improvements to clangd
 --
 
-The improvements are...
+- Background indexing is on by default
+
+  When using clangd, it will build an index of your code base (all files listed
+  in your compile database). This index enables go-to-definition,
+  find-references, and even code completion to find symbols across your 
project.
+
+  This feature can consume a lot of CPU. It can be disabled using the
+  ``--background-index=false`` flag, and respects ``-j`` to use fewer threads.
+  The index is written to ``.clangd/index`` in the project root.
+
+- Contextual code actions
+
+  Extract variable, expand ``auto``, expand macro, convert string to raw 
string.
+  More to come in the future!
+
+- Clang-tidy warnings are available
+
+  These will be produced for projects that have a ``.clang-tidy`` file in their
+  source tree, as described in the :doc:`clang-tidy documentation 
`.
+
+- Improved diagnostics
+
+  Errors from headers are now shown (on the #including line).
+  The message now indicates if fixes are available.
+  Navigation between errors and associated notes is improved (for editors that
+  support ``Diagnostic.relatedInformation``).
+
+- Suggested includes
+
+  When a class or other name is not found, clangd may suggest to fix this by
+  adding the corresponding ``#include`` directive.
+
+- Semantic highlighting
+
+  clangd can push syntax information to the editor, allowing it to highlight
+  e.g. member variables differently from locals. (requires editor support)
+
+  This implements the proposed protocol from
+  https://github.com/microsoft/vscode-languageserver-node/pull/367
+
+- Type hierachy
+
+  Navigation to base/derived types is possible in editors that support the
+  proposed protocol from
+  https://github.com/microsoft/vscode-languageserver-node/pull/426
+
+- Improvements to include insertion
+
+  Only headers with ``#include``-guards will be inserted, and the feature can
+  be disabled with the ``--header-insertion=never`` flag.
+
+  Standard library headers should now be inserted more accurately, particularly
+  for C++ other than libstdc++, and for the C standard library.
+
+- Code completion
+
+  Overloads are bundled into a single completion item by default. (for editors
+  that support signature-help).
+
+  Redundant const/non-const overloads are no longer shown.
+
+  Before clangd is warmed up (during preamble build), limited identifier- and
+  index-based code completion is available.
+
+- Format-on-type
+
+  A new implementation of format-on-type is triggered by hitting enter: it
+  attempts to reformat the previous line and reindent the new line.
+  (Requires editor support).
+
+- Toolchain header detection
+
+  Projects that use an embedded gcc toolchain may only work when used with the
+  corresponding standard library. clangd can now query the toolchain to find
+  these headers.
+  The compilation database must correctly specify this toolchain, and the
+  ``--query-driver=/path/to/toolchain/bin/*`` flag must be passed to clangd.
+
+- Miscellaneous improvements
+
+  Hover now produces richer Markdown-formatted text (for supported editors).
+
+  Rename is safer and more helpful, though is still within one file only.
+
+  Files without extensions (e.g. C++ standard library) are handled better.
+
+  clangd can understand offsets in UTF-8 or UTF-32 through command-line flags 
or
+  protocol extensions. (Useful with editors/platforms that don't speak UTF-16).
+
+  Editors that support edits near the cursor in code-completion can set the
+  ``textDocument.completion.editsNearCursor`` capability to ``true``, and 
clangd
+  will provide completions that correct ``.`` to ``->``, and vice-versa.
 
 Improvements to clang-doc
 -


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 1f6c9be - [docs] clangd release notes

2020-02-25 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-02-25T15:49:43+01:00
New Revision: 1f6c9becd57af14ee71fb7c1e56b55f556be98fa

URL: 
https://github.com/llvm/llvm-project/commit/1f6c9becd57af14ee71fb7c1e56b55f556be98fa
DIFF: 
https://github.com/llvm/llvm-project/commit/1f6c9becd57af14ee71fb7c1e56b55f556be98fa.diff

LOG: [docs] clangd release notes

Added: 


Modified: 
clang-tools-extra/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 52e98cb23f50..86ff28cfb0fd 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -47,7 +47,50 @@ Major New Features
 Improvements to clangd
 --
 
-The improvements are...
+- Go-to-definition, hover, find-references etc use a new mechanism to identify
+  what is under the cursor, which is (hopefully) more consistent and accurate.
+
+- clangd should be able to reliably locate the standard library/SDK on macOS.
+
+- Shutdown more cleanly on receiving a signal. In particular temporary PCH 
files
+  should be cleaned up.
+
+- Find references now works on macros.
+
+- clangd can be more easily used remotely or in a docker container.
+
+  The `--path-mappings` flag translates between local and remote paths.
+
+- Experimental support for renaming across files (behind the
+  `--cross-file-rename` flag).
+
+- Hover now exposes more information, including the type of symbols and the
+  value of constant expressions.
+
+- Go to definition now works in dependent code in more cases, by assuming the
+  primary template is used.
+
+- Better recovery and reporting when the compile command for a file can't be
+  fully parsed.
+
+- Switch header/source (an extension) now uses index information in addition
+  to filename heuristics, and is much more robust.
+
+- Semantic selection (expand/contract selection) is supported.
+
+- Semantic highlighting is more robust, highlights more types of tokens, and
+  as an extension provides information about inactive preprocessor regions.
+
+- Code completion results now include an extension field `score`.
+
+  This allows clients to incorporate clangd quality signals when re-ranking 
code
+  completion after client-side fuzzy-matching.
+
+- New refactorings:
+  define function out-of-line, define function in-line, extract function,
+  remove using namespace directive, localize Objective-C string.
+
+- Bug fixes and performance improvements :-)
 
 Improvements to clang-doc
 -



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 30d05b8 - [clangd][Hover] Handle uninstantiated default args

2020-06-10 Thread Sam McCall via llvm-branch-commits

Author: Kadir Cetinkaya
Date: 2020-06-10T11:53:19+02:00
New Revision: 30d05b898c6e84160507a66aabba6aceb129a9c7

URL: 
https://github.com/llvm/llvm-project/commit/30d05b898c6e84160507a66aabba6aceb129a9c7
DIFF: 
https://github.com/llvm/llvm-project/commit/30d05b898c6e84160507a66aabba6aceb129a9c7.diff

LOG: [clangd][Hover] Handle uninstantiated default args

Summary:
Default args might exist but be unparsed or uninstantiated.
getDefaultArg asserts on those. This patch makes sure we don't crash in such
scenarios.

Reviewers: sammccall, ilya-biryukov

Subscribers: MaskRay, jkorous, arphaman, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D73723

(cherry-picked from commit 9c903d0373ff940f9143efab8d948edf776de9f1)

Fixes https://github.com/clangd/clangd/issues/424

Added: 


Modified: 
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Hover.cpp 
b/clang-tools-extra/clangd/Hover.cpp
index 834c9d041872..e41b4b8e5e1d 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -249,6 +249,20 @@ void enhanceFromIndex(HoverInfo &Hover, const NamedDecl 
&ND,
   Req, [&](const Symbol &S) { Hover.Documentation = S.Documentation; });
 }
 
+// Default argument might exist but be unavailable, in the case of unparsed
+// arguments for example. This function returns the default argument if it is
+// available.
+const Expr *getDefaultArg(const ParmVarDecl *PVD) {
+  // Default argument can be unparsed or uninstatiated. For the former we
+  // can't do much, as token information is only stored in Sema and not
+  // attached to the AST node. For the latter though, it is safe to proceed as
+  // the expression is still valid.
+  if (!PVD->hasDefaultArg() || PVD->hasUnparsedDefaultArg())
+return nullptr;
+  return PVD->hasUninstantiatedDefaultArg() ? 
PVD->getUninstantiatedDefaultArg()
+: PVD->getDefaultArg();
+}
+
 // Populates Type, ReturnType, and Parameters for function-like decls.
 void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
const FunctionDecl *FD,
@@ -268,10 +282,10 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl 
*D,
 }
 if (!PVD->getName().empty())
   P.Name = PVD->getNameAsString();
-if (PVD->hasDefaultArg()) {
+if (const Expr *DefArg = getDefaultArg(PVD)) {
   P.Default.emplace();
   llvm::raw_string_ostream Out(*P.Default);
-  PVD->getDefaultArg()->printPretty(Out, nullptr, Policy);
+  DefArg->printPretty(Out, nullptr, Policy);
 }
   }
 

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp 
b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index bdac5be0ac35..89b529d9b419 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -1615,6 +1615,22 @@ TEST(Hover, All) {
 HI.Type = "unsigned long";
 HI.Value = "1";
   }},
+  {
+  R"cpp(
+  template 
+  void foo(const T& = T()) {
+[[f^oo]]<>(3);
+  })cpp",
+  [](HoverInfo &HI) {
+HI.Name = "foo";
+HI.Kind = index::SymbolKind::Function;
+HI.Type = "void (const int &)";
+HI.ReturnType = "void";
+HI.Parameters = {
+{std::string("const int &"), llvm::None, std::string("T()")}};
+HI.Definition = "template <> void foo(const int &)";
+HI.NamespaceScope = "";
+  }},
   };
 
   // Create a tiny index, so tests above can verify documentation is fetched.



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 52f2d6d - [clangd] Disable all dependency outputs

2020-06-10 Thread Sam McCall via llvm-branch-commits

Author: Kadir Cetinkaya
Date: 2020-06-10T12:00:38+02:00
New Revision: 52f2d6d4b20dbc4c72f87c27e6e7375496fe0e38

URL: 
https://github.com/llvm/llvm-project/commit/52f2d6d4b20dbc4c72f87c27e6e7375496fe0e38
DIFF: 
https://github.com/llvm/llvm-project/commit/52f2d6d4b20dbc4c72f87c27e6e7375496fe0e38.diff

LOG: [clangd] Disable all dependency outputs

Summary: Fixes https://github.com/clangd/clangd/issues/322

Reviewers: sammccall

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

Tags: #clang

Differential Revision: https://reviews.llvm.org/D78833

(cherry picked from commit 294b9d43cae77ea15453ec82203368903db4f538)

Fixes https://github.com/clangd/clangd/issues/422

Added: 
clang-tools-extra/clangd/test/dependency-output.test

Modified: 
clang-tools-extra/clangd/Compiler.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Compiler.cpp 
b/clang-tools-extra/clangd/Compiler.cpp
index eae753b5c9b3..47cec5ae12e8 100644
--- a/clang-tools-extra/clangd/Compiler.cpp
+++ b/clang-tools-extra/clangd/Compiler.cpp
@@ -65,6 +65,15 @@ buildCompilerInvocation(const ParseInputs &Inputs,
   CI->getFrontendOpts().DisableFree = false;
   CI->getLangOpts()->CommentOpts.ParseAllComments = true;
   CI->getLangOpts()->RetainCommentsFromSystemHeaders = true;
+
+  // Disable any dependency outputting, we don't want to generate files or 
write
+  // to stdout/stderr.
+  CI->getDependencyOutputOpts().ShowIncludesDest =
+  ShowIncludesDestination::None;
+  CI->getDependencyOutputOpts().OutputFile.clear();
+  CI->getDependencyOutputOpts().HeaderIncludeOutputFile.clear();
+  CI->getDependencyOutputOpts().DOTOutputFile.clear();
+  CI->getDependencyOutputOpts().ModuleDependencyOutputDir.clear();
   return CI;
 }
 

diff  --git a/clang-tools-extra/clangd/test/dependency-output.test 
b/clang-tools-extra/clangd/test/dependency-output.test
new file mode 100644
index ..10b493d6611d
--- /dev/null
+++ b/clang-tools-extra/clangd/test/dependency-output.test
@@ -0,0 +1,12 @@
+# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
+{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}}
+---
+{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"compilationDatabaseChanges":{"/clangd-test/foo.c":
+{"workingDirectory":"/clangd-test", "compilationCommand": ["clang", "-c", 
"-Xclang", "--show-includes", "-Xclang", "-sys-header-deps", "foo.c"]}
+---
+{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.c","languageId":"cpp","version":1,"text":"int
 a;\n#include "}}}
+#CHECK-NOT: Note: including file
+---
+{"jsonrpc":"2.0","id":3,"method":"shutdown"}
+---
+{"jsonrpc":"2.0","method":"exit"}



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 357e79c - [clangd] Fix early selection for non-vardecl declarators

2020-06-10 Thread Sam McCall via llvm-branch-commits

Author: Kadir Cetinkaya
Date: 2020-06-10T13:44:26+02:00
New Revision: 357e79c2895736c9d202c79380e3e1f507080df3

URL: 
https://github.com/llvm/llvm-project/commit/357e79c2895736c9d202c79380e3e1f507080df3
DIFF: 
https://github.com/llvm/llvm-project/commit/357e79c2895736c9d202c79380e3e1f507080df3.diff

LOG: [clangd] Fix early selection for non-vardecl declarators

Summary:
Selection tree was performing an early claim only for VarDecls, but
there are other cases where we can have declarators, e.g. FieldDecls. This patch
extends the early claim logic to all types of declarators.

Fixes https://github.com/clangd/clangd/issues/292

Reviewers: sammccall

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

Tags: #clang

Differential Revision: https://reviews.llvm.org/D75106

(cherry picked from commit e6b8181895b96740dbe54aca036aa237e0a8363d)

Modified the cherry-picked test as diagnostics differ on the branch.

Fixes https://github.com/clangd/clangd/issues/421

Added: 


Modified: 
clang-tools-extra/clangd/Selection.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp
clang-tools-extra/clangd/unittests/SelectionTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Selection.cpp 
b/clang-tools-extra/clangd/Selection.cpp
index 14c05d1c0b49..d7630f4481f2 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -10,6 +10,7 @@
 #include "Logger.h"
 #include "SourceCode.h"
 #include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
@@ -594,13 +595,23 @@ class SelectionVisitor : public 
RecursiveASTVisitor {
   // Usually empty, but sometimes children cover tokens but shouldn't own them.
   SourceRange earlySourceRange(const DynTypedNode &N) {
 if (const Decl *D = N.get()) {
+  // We want constructor name to be claimed by TypeLoc not the constructor
+  // itself. Similar for deduction guides, we rather want to select the
+  // underlying TypeLoc.
+  // FIXME: Unfortunately this doesn't work, even though 
RecursiveASTVisitor
+  // traverses the underlying TypeLoc inside DeclarationName, it is null 
for
+  // constructors.
+  if (isa(D) || isa(D))
+return SourceRange();
+  // This will capture Field, Function, MSProperty, NonTypeTemplateParm and
+  // VarDecls. We want the name in the declarator to be claimed by the decl
+  // and not by any children. For example:
   // void [[foo]]();
-  if (auto *FD = llvm::dyn_cast(D))
-return FD->getNameInfo().getSourceRange();
   // int (*[[s]])();
-  else if (auto *VD = llvm::dyn_cast(D))
-return VD->getLocation();
-} else if (const auto* CCI = N.get()) {
+  // struct X { int [[hash]] [32]; [[operator]] int();}
+  if (const auto *DD = llvm::dyn_cast(D))
+return DD->getLocation();
+} else if (const auto *CCI = N.get()) {
   // : [[b_]](42)
   return CCI->getMemberLocation();
 }

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp 
b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 89b529d9b419..eb47b5a541a6 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -339,7 +339,7 @@ class Foo {})cpp";
  HI.Definition = "~X()";
  HI.Parameters.emplace();
}},
-  {"class X { operator [[in^t]](); };",
+  {"class X { [[op^erator]] int(); };",
[](HoverInfo &HI) {
  HI.NamespaceScope = "";
  HI.Name = "operator int";
@@ -348,6 +348,13 @@ class Foo {})cpp";
  HI.Definition = "operator int()";
  HI.Parameters.emplace();
}},
+  {"class X { operator [[^X]]*(); };",
+   [](HoverInfo &HI) {
+ HI.NamespaceScope = "";
+ HI.Name = "X";
+ HI.Kind = index::SymbolKind::Class;
+ HI.Definition = "class X {}";
+   }},
 
   // auto on lambda
   {R"cpp(

diff  --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp 
b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index 581309b1dccc..0cd9ca09401e 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -329,6 +329,12 @@ TEST(SelectionTest, CommonAncestor) {
 decltype([[^a]] + a) b;
 )cpp",
   "DeclRefExpr"},
+
+  {"struct foo { [[int has^h<:32:>]]; };", "FieldDecl"},
+  {"struct foo { [[op^erator int()]]; };", "CXXConversionDecl"},
+  {"struct foo { [[^~foo()]]; };", "CXXDestructorDecl"},
+  // FIXME: The following to should be class itself instead.
+  {"struct foo { [[fo^o(){}]] };", "CXXConstructorDecl"},
   };
   for (const Case &C : Cases) {
 Annotations Test(C.Code);




[llvm-branch-commits] [clang-tools-extra] cb89646 - [clangd] Filter pch related flags coming from the user

2020-06-10 Thread Sam McCall via llvm-branch-commits

Author: Kadir Cetinkaya
Date: 2020-06-10T13:53:27+02:00
New Revision: cb89646a4a888b8721adbc746e167f31fd484c11

URL: 
https://github.com/llvm/llvm-project/commit/cb89646a4a888b8721adbc746e167f31fd484c11
DIFF: 
https://github.com/llvm/llvm-project/commit/cb89646a4a888b8721adbc746e167f31fd484c11.diff

LOG: [clangd] Filter pch related flags coming from the user

Summary:
PCH format is unstable, hence using a preamble built with a different
version of clang (or even worse, a different compiler) might result in
unexpected behaviour.

PCH creation on the other hand is something clangd wouldn't want to perform, as
it doesn't generate any output files.

This patch makes sure clangd drops any PCH related compile commands after
parsing the command line args.

Fixes https://github.com/clangd/clangd/issues/248

Reviewers: sammccall

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

Tags: #clang

Differential Revision: https://reviews.llvm.org/D79669

(cherry picked from commit 35d867a790c2bcf2008b2ee1895ae8af2793b797)

Dropped the test as it depends on nontrivial changes from master.
The code is very simple and identical to that tested on master.

Fixes https://github.com/clangd/clangd/issues/419

Added: 


Modified: 
clang-tools-extra/clangd/Compiler.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Compiler.cpp 
b/clang-tools-extra/clangd/Compiler.cpp
index 47cec5ae12e8..f4a913708ef7 100644
--- a/clang-tools-extra/clangd/Compiler.cpp
+++ b/clang-tools-extra/clangd/Compiler.cpp
@@ -41,8 +41,7 @@ void 
IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
 }
 
 std::unique_ptr
-buildCompilerInvocation(const ParseInputs &Inputs,
-clang::DiagnosticConsumer &D,
+buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer 
&D,
 std::vector *CC1Args) {
   std::vector ArgStrs;
   for (const auto &S : Inputs.CompileCommand.CommandLine)
@@ -74,6 +73,15 @@ buildCompilerInvocation(const ParseInputs &Inputs,
   CI->getDependencyOutputOpts().HeaderIncludeOutputFile.clear();
   CI->getDependencyOutputOpts().DOTOutputFile.clear();
   CI->getDependencyOutputOpts().ModuleDependencyOutputDir.clear();
+
+  // Disable any pch generation/usage operations. Since serialized preamble
+  // format is unstable, using an incompatible one might result in unexpected
+  // behaviours, including crashes.
+  CI->getPreprocessorOpts().ImplicitPCHInclude.clear();
+  CI->getPreprocessorOpts().PrecompiledPreambleBytes = {0, false};
+  CI->getPreprocessorOpts().PCHThroughHeader.clear();
+  CI->getPreprocessorOpts().PCHWithHdrStop = false;
+  CI->getPreprocessorOpts().PCHWithHdrStopCreate = false;
   return CI;
 }
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] d623a06 - [clangd] Make use of SourceOrder to find first initializer in DefineOutline

2020-06-10 Thread Sam McCall via llvm-branch-commits

Author: Kadir Cetinkaya
Date: 2020-06-10T13:57:00+02:00
New Revision: d623a06a8247b1a04e74ad5f02a30ef351697e00

URL: 
https://github.com/llvm/llvm-project/commit/d623a06a8247b1a04e74ad5f02a30ef351697e00
DIFF: 
https://github.com/llvm/llvm-project/commit/d623a06a8247b1a04e74ad5f02a30ef351697e00.diff

LOG: [clangd] Make use of SourceOrder to find first initializer in DefineOutline

Summary:
Constructors can have implicit initializers, this was crashing define
outline. Make sure we find the first "written" ctor initializer to figure out
`:` location.

Fixes https://github.com/clangd/clangd/issues/400

Reviewers: sammccall

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

Tags: #clang

Differential Revision: https://reviews.llvm.org/D80521

(cherry picked from commit eeedbd033612e105755156023bdeec2fba4eca21)

Fixes https://github.com/clangd/clangd/issues/418

Added: 


Modified: 
clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
clang-tools-extra/clangd/unittests/TweakTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index ca3d74b8dcac..1dd96c5c6584 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -306,18 +306,16 @@ SourceRange getDeletionRange(const FunctionDecl *FD,
  const syntax::TokenBuffer &TokBuf) {
   auto DeletionRange = FD->getBody()->getSourceRange();
   if (auto *CD = llvm::dyn_cast(FD)) {
-const auto &SM = TokBuf.sourceManager();
 // AST doesn't contain the location for ":" in ctor initializers. Therefore
 // we find it by finding the first ":" before the first ctor initializer.
 SourceLocation InitStart;
 // Find the first initializer.
 for (const auto *CInit : CD->inits()) {
-  // We don't care about in-class initializers.
-  if (CInit->isInClassMemberInitializer())
+  // SourceOrder is -1 for implicit initializers.
+  if (CInit->getSourceOrder() != 0)
 continue;
-  if (InitStart.isInvalid() ||
-  SM.isBeforeInTranslationUnit(CInit->getSourceLocation(), InitStart))
-InitStart = CInit->getSourceLocation();
+  InitStart = CInit->getSourceLocation();
+  break;
 }
 if (InitStart.isValid()) {
   auto Toks = TokBuf.expandedTokens(CD->getSourceRange());

diff  --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp 
b/clang-tools-extra/clangd/unittests/TweakTests.cpp
index adbdbe71761d..9b2db764cb0e 100644
--- a/clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ b/clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2047,21 +2047,57 @@ TEST_F(DefineOutlineTest, ApplyTest) {
   "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
   "void foo(int x, int y , int , int (*foo)(int) ) {}",
   },
-  // Ctor initializers.
+  // Constructors
+  {
+  R"cpp(
+class Foo {public: Foo(); Foo(int);};
+class Bar {
+  Ba^r() {}
+  Bar(int x) : f1(x) {}
+  Foo f1;
+  Foo f2 = 2;
+};)cpp",
+  R"cpp(
+class Foo {public: Foo(); Foo(int);};
+class Bar {
+  Bar() ;
+  Bar(int x) : f1(x) {}
+  Foo f1;
+  Foo f2 = 2;
+};)cpp",
+  "Bar::Bar() {}\n",
+  },
+  // Ctor with initializer.
+  {
+  R"cpp(
+class Foo {public: Foo(); Foo(int);};
+class Bar {
+  Bar() {}
+  B^ar(int x) : f1(x), f2(3) {}
+  Foo f1;
+  Foo f2 = 2;
+};)cpp",
+  R"cpp(
+class Foo {public: Foo(); Foo(int);};
+class Bar {
+  Bar() {}
+  Bar(int x) ;
+  Foo f1;
+  Foo f2 = 2;
+};)cpp",
+  "Bar::Bar(int x) : f1(x), f2(3) {}\n",
+  },
+  // Ctor initializer with attribute.
   {
   R"cpp(
   class Foo {
-int y = 2;
 F^oo(int z) __attribute__((weak)) : bar(2){}
 int bar;
-int z = 2;
   };)cpp",
   R"cpp(
   class Foo {
-int y = 2;
 Foo(int z) __attribute__((weak)) ;
 int bar;
-int z = 2;
   };)cpp",
   "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
   },



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] 230b872 - [clangd] Increase stack size of the new threads on macOS

2020-06-10 Thread Sam McCall via llvm-branch-commits

Author: Sam McCall
Date: 2020-06-10T14:08:14+02:00
New Revision: 230b872c290d8c80a60accb06f3267e0703d0c49

URL: 
https://github.com/llvm/llvm-project/commit/230b872c290d8c80a60accb06f3267e0703d0c49
DIFF: 
https://github.com/llvm/llvm-project/commit/230b872c290d8c80a60accb06f3267e0703d0c49.diff

LOG: [clangd] Increase stack size of the new threads on macOS

Summary: By default it's 512K, which is way to small for clang parser to run 
on. There is no way to do it via platform-independent API, so it's implemented 
via pthreads directly in clangd/Threading.cpp.

Fixes https://github.com/clangd/clangd/issues/273

Patch by Dmitry Kozhevnikov!

Reviewers: ilya-biryukov, sammccall, arphaman

Reviewed By: ilya-biryukov, sammccall, arphaman

Subscribers: dexonsmith, umanwizard, jfb, ioeric, MaskRay, jkorous, arphaman, 
kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D50993

(cherry picked from commit 69a39dc1f0d08ea43bac03a87bb8bff3937ce2e7)

Added: 


Modified: 
clang-tools-extra/clangd/Threading.cpp
clang-tools-extra/clangd/unittests/ClangdTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Threading.cpp 
b/clang-tools-extra/clangd/Threading.cpp
index 016a90297c32..0a605719fce2 100644
--- a/clang-tools-extra/clangd/Threading.cpp
+++ b/clang-tools-extra/clangd/Threading.cpp
@@ -1,5 +1,6 @@
 #include "Threading.h"
 #include "Trace.h"
+#include "clang/Basic/Stack.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Threading.h"
@@ -84,16 +85,16 @@ void AsyncTaskRunner::runAsync(const llvm::Twine &Name,
 }
   });
 
-  std::thread(
-  [](std::string Name, decltype(Action) Action, decltype(CleanupTask)) {
-llvm::set_thread_name(Name);
-Action();
-// Make sure function stored by Action is destroyed before CleanupTask
-// is run.
-Action = nullptr;
-  },
-  Name.str(), std::move(Action), std::move(CleanupTask))
-  .detach();
+  auto Task = [Name = Name.str(), Action = std::move(Action),
+   Cleanup = std::move(CleanupTask)]() mutable {
+llvm::set_thread_name(Name);
+Action();
+// Make sure function stored by ThreadFunc is destroyed before Cleanup 
runs.
+Action = nullptr;
+  };
+
+  // Ensure our worker threads have big enough stacks to run clang.
+  llvm::llvm_execute_on_thread_async(std::move(Task), clang::DesiredStackSize);
 }
 
 Deadline timeoutSeconds(llvm::Optional Seconds) {

diff  --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp 
b/clang-tools-extra/clangd/unittests/ClangdTests.cpp
index ab88c8925da0..99fd41e29ab7 100644
--- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp
@@ -1063,6 +1063,27 @@ TEST_F(ClangdVFSTest, 
FallbackWhenWaitingForCompileCommand) {
 Field(&CodeCompletion::Scope, "ns::";
 }
 
+TEST_F(ClangdVFSTest, TestStackOverflow) {
+  MockFSProvider FS;
+  ErrorCheckingDiagConsumer DiagConsumer;
+  MockCompilationDatabase CDB;
+  ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest());
+
+  const char *SourceContents = R"cpp(
+constexpr int foo() { return foo(); }
+static_assert(foo());
+  )cpp";
+
+  auto FooCpp = testPath("foo.cpp");
+  FS.Files[FooCpp] = SourceContents;
+
+  Server.addDocument(FooCpp, SourceContents);
+  ASSERT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for diagnostics";
+  // check that we got a constexpr depth error, and not crashed by stack
+  // overflow
+  EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] c900824 - [clangd] Fix a crash for accessing a null template decl returned by findExplicitReferences.

2020-06-10 Thread Sam McCall via llvm-branch-commits

Author: Haojian Wu
Date: 2020-06-10T16:07:41+02:00
New Revision: c90082432021360fae9f838502479b9113854de4

URL: 
https://github.com/llvm/llvm-project/commit/c90082432021360fae9f838502479b9113854de4
DIFF: 
https://github.com/llvm/llvm-project/commit/c90082432021360fae9f838502479b9113854de4.diff

LOG: [clangd] Fix a crash for accessing a null template decl returned by 
findExplicitReferences.

Summary: Fixes https://github.com/clangd/clangd/issues/347.

Reviewers: kadircet

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

Tags: #clang

Differential Revision: https://reviews.llvm.org/D78626

(cherry picked from commit 7d1ee639cb9efea364bec90afe4d1161ec624a7f)
Includes some test-only changes from f651c402a221a20f3bc6ea43f70b29326a357010
to support the cherry-picked tests.
Test tweaked slightly as it exhibits a separate bug that was fixed on master.

Added: 


Modified: 
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/FindTarget.cpp 
b/clang-tools-extra/clangd/FindTarget.cpp
index 5912464b0ed0..7a4f651b3620 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -759,15 +759,17 @@ class ExplicitReferenceCollector
   // TemplateArgumentLoc is the only way to get locations for references to
   // template template parameters.
   bool TraverseTemplateArgumentLoc(TemplateArgumentLoc A) {
+llvm::SmallVector Targets;
 switch (A.getArgument().getKind()) {
 case TemplateArgument::Template:
 case TemplateArgument::TemplateExpansion:
+  if (const auto *D = A.getArgument()
+  .getAsTemplateOrTemplatePattern()
+  .getAsTemplateDecl())
+Targets.push_back(D);
   reportReference(ReferenceLoc{A.getTemplateQualifierLoc(),
A.getTemplateNameLoc(),
-   /*IsDecl=*/false,
-   {A.getArgument()
-.getAsTemplateOrTemplatePattern()
-.getAsTemplateDecl()}},
+   /*IsDecl=*/false, Targets},
   DynTypedNode::create(A.getArgument()));
   break;
 case TemplateArgument::Declaration:

diff  --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp 
b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 9c1020b7a189..ae16c608fd33 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -589,12 +589,21 @@ class FindExplicitReferencesTest : public ::testing::Test 
{
 auto *TestDecl = &findDecl(AST, "foo");
 if (auto *T = llvm::dyn_cast(TestDecl))
   TestDecl = T->getTemplatedDecl();
-auto &Func = llvm::cast(*TestDecl);
 
 std::vector Refs;
-findExplicitReferences(Func.getBody(), [&Refs](ReferenceLoc R) {
-  Refs.push_back(std::move(R));
-});
+if (const auto *Func = llvm::dyn_cast(TestDecl))
+  findExplicitReferences(Func->getBody(), [&Refs](ReferenceLoc R) {
+Refs.push_back(std::move(R));
+  });
+else if (const auto *NS = llvm::dyn_cast(TestDecl))
+  findExplicitReferences(NS, [&Refs, &NS](ReferenceLoc R) {
+// Avoid adding the namespace foo decl to the results.
+if (R.Targets.size() == 1 && R.Targets.front() == NS)
+  return;
+Refs.push_back(std::move(R));
+  });
+else
+  ADD_FAILURE() << "Failed to find ::foo decl for test";
 
 auto &SM = AST.getSourceManager();
 llvm::sort(Refs, [&](const ReferenceLoc &L, const ReferenceLoc &R) {
@@ -984,7 +993,24 @@ TEST_F(FindExplicitReferencesTest, All) {
   }
 )cpp",
"0: targets = {Test}\n"
-   "1: targets = {a}, decl\n"}};
+   "1: targets = {a}, decl\n"},
+  // unknown template name should not crash.
+  // duplicate $1$2 is fixed on master.
+  {R"cpp(
+template  typename T>
+struct Base {};
+namespace foo {
+template 
+struct $1^$2^Derive : $3^Base<$4^T::template $5^Unknown> {};
+}
+  )cpp",
+  "0: targets = {foo::Derive::T}, decl\n"
+  "1: targets = {foo::Derive}, decl\n"
+  "2: targets = {foo::Derive}, decl\n"
+  "3: targets = {Base}\n"
+  "4: targets = {foo::Derive::T}\n"
+  "5: targets = {}, qualifier = 'T::'\n"},
+};
 
   for (const auto &C : Cases) {
 llvm::StringRef ExpectedCode = C.first;



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang-tools-extra] b6efa23 - [clangd] Preserve -nostdinc and --sysroot when calling query driver

2020-06-10 Thread Sam McCall via llvm-branch-commits

Author: Kadir Cetinkaya
Date: 2020-06-10T17:42:39+02:00
New Revision: b6efa2365812f31667485c8948d49621ebf952f2

URL: 
https://github.com/llvm/llvm-project/commit/b6efa2365812f31667485c8948d49621ebf952f2
DIFF: 
https://github.com/llvm/llvm-project/commit/b6efa2365812f31667485c8948d49621ebf952f2.diff

LOG: [clangd] Preserve -nostdinc and --sysroot when calling query driver

Solves this issue: https://github.com/clangd/clangd/issues/157

This is my first contribution to an llvm project, so I hope I'm doing it right!

Patch by @topisani (Tobias Pisani)!

Reviewers: kadircet, klimek

Differential Revision: https://reviews.llvm.org/D73811

(cherry picked from commit 6e8d6bc9ec8739ec22b73a23f740f171f452e234)

Added: 


Modified: 
clang-tools-extra/clangd/QueryDriverDatabase.cpp
clang-tools-extra/clangd/test/system-include-extractor.test

Removed: 




diff  --git a/clang-tools-extra/clangd/QueryDriverDatabase.cpp 
b/clang-tools-extra/clangd/QueryDriverDatabase.cpp
index 4953da52c324..20eb4f8a28e0 100644
--- a/clang-tools-extra/clangd/QueryDriverDatabase.cpp
+++ b/clang-tools-extra/clangd/QueryDriverDatabase.cpp
@@ -85,9 +85,10 @@ std::vector parseDriverOutput(llvm::StringRef 
Output) {
   return SystemIncludes;
 }
 
-std::vector extractSystemIncludes(PathRef Driver,
-   llvm::StringRef Lang,
-   llvm::Regex &QueryDriverRegex) {
+std::vector
+extractSystemIncludes(PathRef Driver, llvm::StringRef Lang,
+  llvm::ArrayRef CommandLine,
+  llvm::Regex &QueryDriverRegex) {
   trace::Span Tracer("Extract system includes");
   SPAN_ATTACH(Tracer, "driver", Driver);
   SPAN_ATTACH(Tracer, "lang", Lang);
@@ -120,14 +121,43 @@ std::vector extractSystemIncludes(PathRef 
Driver,
   llvm::Optional Redirects[] = {
   {""}, {""}, llvm::StringRef(StdErrPath)};
 
-  // Should we also preserve flags like "-sysroot", "-nostdinc" ?
-  const llvm::StringRef Args[] = {Driver, "-E", "-x", Lang, "-", "-v"};
+  llvm::SmallVector Args = {Driver, "-E", "-x",
+ Lang,   "-",  "-v"};
+
+  // These flags will be preserved
+  const llvm::StringRef FlagsToPreserve[] = {
+  "-nostdinc", "--no-standard-includes", "-nostdinc++", "-nobuiltininc"};
+  // Preserves these flags and their values, either as separate args or with an
+  // equalsbetween them
+  const llvm::StringRef ArgsToPreserve[] = {"--sysroot", "-isysroot"};
+
+  for (size_t I = 0, E = CommandLine.size(); I < E; ++I) {
+llvm::StringRef Arg = CommandLine[I];
+if (llvm::any_of(FlagsToPreserve,
+ [&Arg](llvm::StringRef S) { return S == Arg; })) {
+  Args.push_back(Arg);
+} else {
+  const auto *Found =
+  llvm::find_if(ArgsToPreserve, [&Arg](llvm::StringRef S) {
+return Arg.startswith(S);
+  });
+  if (Found == std::end(ArgsToPreserve))
+continue;
+  Arg.consume_front(*Found);
+  if (Arg.empty() && I + 1 < E) {
+Args.push_back(CommandLine[I]);
+Args.push_back(CommandLine[++I]);
+  } else if (Arg.startswith("=")) {
+Args.push_back(CommandLine[I]);
+  }
+}
+  }
 
   if (int RC = llvm::sys::ExecuteAndWait(Driver, Args, /*Env=*/llvm::None,
  Redirects)) {
 elog("System include extraction: driver execution failed with return code: 
"
- "{0}",
- llvm::to_string(RC));
+ "{0}. Args: ['{1}']",
+ llvm::to_string(RC), llvm::join(Args, "', '"));
 return {};
   }
 
@@ -237,7 +267,7 @@ class QueryDriverDatabase : public 
GlobalCompilationDatabase {
 
 llvm::SmallString<128> Driver(Cmd->CommandLine.front());
 llvm::sys::fs::make_absolute(Cmd->Directory, Driver);
-auto Key = std::make_pair(Driver.str(), Lang);
+auto Key = std::make_pair(Driver.str().str(), Lang.str());
 
 std::vector SystemIncludes;
 {
@@ -247,8 +277,8 @@ class QueryDriverDatabase : public 
GlobalCompilationDatabase {
   if (It != DriverToIncludesCache.end())
 SystemIncludes = It->second;
   else
-DriverToIncludesCache[Key] = SystemIncludes =
-extractSystemIncludes(Key.first, Key.second, QueryDriverRegex);
+DriverToIncludesCache[Key] = SystemIncludes = extractSystemIncludes(
+Key.first, Key.second, Cmd->CommandLine, QueryDriverRegex);
 }
 
 return addSystemIncludes(*Cmd, SystemIncludes);
@@ -278,7 +308,7 @@ getQueryDriverDatabase(llvm::ArrayRef 
QueryDriverGlobs,
   if (QueryDriverGlobs.empty())
 return Base;
   return std::make_unique(QueryDriverGlobs,
-std::move(Base));
+   std::move(Base));
 }
 
 } // namespace clangd

diff  --git a/clang-tools-extra/clangd/test/system-include-ext