[clang-tools-extra] [clangd] Prevent printing huge initializer lists in hover definitions (PR #79746)

Raoul Wols via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 25 09:01:26 PST 2024


https://github.com/rwols updated https://github.com/llvm/llvm-project/pull/79746

>From 6d30615ba3fb59163938656827a60a838e160c31 Mon Sep 17 00:00:00 2001
From: Raoul Wols <raoulwols at gmail.com>
Date: Sat, 10 Feb 2024 20:52:03 +0100
Subject: [PATCH] [clangd] Do not render large initializer expressions from the
 preamble

An attempt is made to estimate the size of the initializer expression.
If it has less than 100 (in)direct AST child nodes we'll assume it should
render OK.
---
 clang-tools-extra/clangd/Hover.cpp            | 14 ++++-
 .../clangd/unittests/HoverTests.cpp           | 51 +++++++++++++++++++
 2 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index 06b949bc4a2b55..c3c5cf2732486d 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -136,6 +136,15 @@ std::string getNamespaceScope(const Decl *D) {
   return "";
 }
 
+/// Compute the number of child statements in this statement. Includes the
+/// statement itself.
+size_t totalChildrenInStmt(const Stmt *Statement) {
+  size_t Count = 1;
+  for (const auto &Child : Statement->children())
+    Count += totalChildrenInStmt(Child);
+  return Count;
+}
+
 std::string printDefinition(const Decl *D, PrintingPolicy PP,
                             const syntax::TokenBuffer &TB) {
   if (auto *VD = llvm::dyn_cast<VarDecl>(D)) {
@@ -143,8 +152,9 @@ std::string printDefinition(const Decl *D, PrintingPolicy PP,
       // Initializers might be huge and result in lots of memory allocations in
       // some catostrophic cases. Such long lists are not useful in hover cards
       // anyway.
-      if (200 < TB.expandedTokens(IE->getSourceRange()).size())
-        PP.SuppressInitializers = true;
+      PP.SuppressInitializers =
+          200 < TB.expandedTokens(IE->getSourceRange()).size() ||
+          100 < totalChildrenInStmt(IE);
     }
   }
   std::string Definition;
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 35db757b9c15b5..9b213da9ec844b 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -3956,6 +3956,57 @@ TEST(Hover, HideBigInitializers) {
   EXPECT_EQ(H->Definition, "int arr[]");
 }
 
+TEST(Hover, HideBigInitializersIncludedFromThePreamble) {
+  Annotations T(R"cpp(
+  #include "hugearray.h"
+  auto x = a^rr;
+  )cpp");
+  TestTU TU = TestTU::withCode(T.code());
+  TU.AdditionalFiles["hugearray.h"] = R"cpp(
+    #define A(x) x, x, x, x
+    #define B(x) A(A(A(A(x))))
+    int arr[256] = {B(0)};
+  )cpp";
+  auto AST = TU.build();
+  auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+  ASSERT_TRUE(H);
+  EXPECT_EQ(H->Definition, "int arr[256]");
+}
+
+TEST(Hover, HideBigNestedInitializersIncludedFromThePreamble) {
+  Annotations T(R"cpp(
+  #include "hugearray.h"
+  auto x = a^rr;
+  )cpp");
+  TestTU TU = TestTU::withCode(T.code());
+  TU.AdditionalFiles["hugearray.h"] = R"cpp(
+    #define A(x) x, x, x, x
+    #define B(x) A(A(A(A(x))))
+    int arr[1][1][256] = {{{B(0)}}};
+  )cpp";
+  auto AST = TU.build();
+  auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+  ASSERT_TRUE(H);
+  EXPECT_EQ(H->Definition, "int arr[1][1][256]");
+}
+
+TEST(Hover, DoNotHideSmallInitializersIncludedFromThePreamble) {
+  Annotations T(R"cpp(
+  #include "smallarray.h"
+  auto x = a^rr;
+  )cpp");
+  TestTU TU = TestTU::withCode(T.code());
+  TU.AdditionalFiles["smallarray.h"] = R"cpp(
+    #define A(x) x, x
+    #define B(x) A(A(x))
+    int arr[4] = {B(0)};
+  )cpp";
+  auto AST = TU.build();
+  auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+  ASSERT_TRUE(H);
+  EXPECT_EQ(H->Definition, "int arr[4] = {0, 0, 0, 0}");
+}
+
 #if defined(__aarch64__)
 // FIXME: AARCH64 sanitizer buildbots are broken after 72142fbac4.
 #define PREDEFINEMACROS_TEST(x) DISABLED_##x



More information about the cfe-commits mailing list