[clang-tools-extra] [llvm] [Clangd] Add AST search capabilities from clang-query (PR #156090)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 29 12:47:57 PDT 2025


Fabian =?utf-8?q?Keßler?= <fabian_kessler at gmx.de>,
Fabian =?utf-8?q?Keßler?= <fabian_kessler at gmx.de>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/156090 at github.com>


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff origin/main HEAD --extensions cpp,h -- 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/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/XRefs.h llvm/include/llvm/Support/JSON.h
``````````

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 5cdf615ed..e064b03fe 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -856,8 +856,7 @@ void ClangdLSPServer::onCommandApplyRename(const RenameParams &R,
 void ClangdLSPServer::onMethodSearchAST(const SearchASTArgs &Args,
                                         Callback<llvm::json::Value> Reply) {
   Server->findAST(Args, [Reply = std::move(Reply)](
-                            llvm::Expected<BoundASTNodes>
-                                BoundNodes) mutable {
+                            llvm::Expected<BoundASTNodes> BoundNodes) mutable {
     if (!BoundNodes)
       return Reply(BoundNodes.takeError());
     return Reply(*BoundNodes);
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 03f220af1..e2473dd7d 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -812,35 +812,35 @@ void ClangdServer::locateSymbolAt(PathRef File, Position Pos,
 
 void ClangdServer::findAST(SearchASTArgs const &Args,
                            Callback<BoundASTNodes> CB) {
-  auto Action =
-      [Args, CB = std::move(CB)](llvm::Expected<InputsAndAST> InpAST) mutable {
-        if (!InpAST)
-          return CB(InpAST.takeError());
-        auto BoundNodes = clangd::locateASTQuery(InpAST->AST, Args);
-        if (!BoundNodes)
-          return CB(BoundNodes.takeError());
-        if (BoundNodes->empty())
-          return CB(error("No matching AST nodes found"));
-
-        auto &&AST = InpAST->AST;
-        // Convert BoundNodes to a vector of vectors to ASTNode's.
-        BoundASTNodes Result;
-        Result.reserve(BoundNodes->size());
-        for (auto &&BN : *BoundNodes) {
-          auto &&Map = BN.getMap();
-          BoundASTNodes::value_type BAN;
-          for (const auto &[Key, Value] : Map) {
-            BAN.emplace(Key, dumpAST(Value, AST.getTokens(), AST.getASTContext()));
-          }
-          if (BAN.empty())
-            continue;
-          Result.push_back(std::move(BAN));
-        }
-        if (Result.empty()) {
-          return CB(error("No AST nodes found for the query"));
-        }
-        CB(std::move(Result));
-      };
+  auto Action = [Args, CB = std::move(CB)](
+                    llvm::Expected<InputsAndAST> InpAST) mutable {
+    if (!InpAST)
+      return CB(InpAST.takeError());
+    auto BoundNodes = clangd::locateASTQuery(InpAST->AST, Args);
+    if (!BoundNodes)
+      return CB(BoundNodes.takeError());
+    if (BoundNodes->empty())
+      return CB(error("No matching AST nodes found"));
+
+    auto &&AST = InpAST->AST;
+    // Convert BoundNodes to a vector of vectors to ASTNode's.
+    BoundASTNodes Result;
+    Result.reserve(BoundNodes->size());
+    for (auto &&BN : *BoundNodes) {
+      auto &&Map = BN.getMap();
+      BoundASTNodes::value_type BAN;
+      for (const auto &[Key, Value] : Map) {
+        BAN.emplace(Key, dumpAST(Value, AST.getTokens(), AST.getASTContext()));
+      }
+      if (BAN.empty())
+        continue;
+      Result.push_back(std::move(BAN));
+    }
+    if (Result.empty()) {
+      return CB(error("No AST nodes found for the query"));
+    }
+    CB(std::move(Result));
+  };
 
   WorkScheduler->runWithAST("Definitions", Args.textDocument.uri.file(),
                             std::move(Action));
diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h
index 7a299f89c..0fd3f15b9 100644
--- a/clang-tools-extra/clangd/ClangdServer.h
+++ b/clang-tools-extra/clangd/ClangdServer.h
@@ -263,8 +263,7 @@ public:
   void locateSymbolAt(PathRef File, Position Pos,
                       Callback<std::vector<LocatedSymbol>> CB);
 
-  void findAST(const SearchASTArgs &Args,
-               Callback<BoundASTNodes> CB);
+  void findAST(const SearchASTArgs &Args, Callback<BoundASTNodes> CB);
 
   /// Switch to a corresponding source file when given a header file, and vice
   /// versa.
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index 70e684582..1f418db39 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -1654,13 +1654,16 @@ bool fromJSON(const llvm::json::Value &Params, SelectionRangeParams &S,
          O.map("positions", S.positions);
 }
 
-bool fromJSON(const llvm::json::Value &Params, SearchASTArgs &Args, llvm::json::Path P) {
+bool fromJSON(const llvm::json::Value &Params, SearchASTArgs &Args,
+              llvm::json::Path P) {
   llvm::json::ObjectMapper O(Params, P);
-  return O && O.map("query", Args.searchQuery)
-  && O.map("textDocument", Args.textDocument)
-  // && O.map("bindRoot", Args.bindRoot); TODO: add bindRoot to extend this feature
-  // && O.map("traversalKind", Args.tk); TODO: add traversalKind to extend this feature
-  ;
+  return O && O.map("query", Args.searchQuery) &&
+         O.map("textDocument", Args.textDocument)
+      // && O.map("bindRoot", Args.bindRoot); TODO: add bindRoot to extend this
+      // feature
+      // && O.map("traversalKind", Args.tk); TODO: add traversalKind to extend
+      // this feature
+      ;
 }
 
 llvm::json::Value toJSON(const SelectionRange &Out) {
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index 0c0c09339..ea9da2adf 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -799,7 +799,6 @@ auto locateASTQuery(ParsedAST &AST, SearchASTArgs const &Query)
     return error("Not a valid top-level matcher: {}.", Diag.toString());
   }
 
-
   struct CollectBoundNodes : MatchFinder::MatchCallback {
     std::vector<BoundNodes> *Bindings;
     CollectBoundNodes(std::vector<BoundNodes> &Bindings)

``````````

</details>


https://github.com/llvm/llvm-project/pull/156090


More information about the llvm-commits mailing list