[clang] [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 Jan 28 05:19:56 PST 2024


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

Previously we checked whether we were dealing with a large initializer using TokenBuffer::expandedTokens. However, TokenBuffer does not contain the tokens of the preamble. This causes large arrays imported from an #include to still print all their elements. The added unit test checks the case of a large array included from the preamble.

>From 27bc0b64e17afce3196eb8d8415a8c61619dfae2 Mon Sep 17 00:00:00 2001
From: Raoul Wols <raoulwols at gmail.com>
Date: Sun, 28 Jan 2024 14:14:29 +0100
Subject: [PATCH] [clangd] Prevent printing huge initializer lists in hover
 definitions

---
 clang-tools-extra/clangd/Hover.cpp            | 12 +++--------
 .../clangd/unittests/HoverTests.cpp           | 21 ++++++++++++++++++-
 clang/lib/AST/StmtPrinter.cpp                 |  6 ++++++
 3 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index 06b949bc4a2b552..ed70b3e97d39ccd 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -138,15 +138,9 @@ std::string getNamespaceScope(const Decl *D) {
 
 std::string printDefinition(const Decl *D, PrintingPolicy PP,
                             const syntax::TokenBuffer &TB) {
-  if (auto *VD = llvm::dyn_cast<VarDecl>(D)) {
-    if (auto *IE = VD->getInit()) {
-      // 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;
-    }
-  }
+  // 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.
+  PP.EntireContentsOfLargeArray = false;
   std::string Definition;
   llvm::raw_string_ostream OS(Definition);
   D->print(OS, PP);
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 35db757b9c15b5d..c2d7dd406c1dc66 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -3953,9 +3953,28 @@ TEST(Hover, HideBigInitializers) {
   auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
 
   ASSERT_TRUE(H);
-  EXPECT_EQ(H->Definition, "int arr[]");
+  EXPECT_EQ(H->Definition, "int arr[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...}");
 }
 
+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] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...}");
+}
+
+
 #if defined(__aarch64__)
 // FIXME: AARCH64 sanitizer buildbots are broken after 72142fbac4.
 #define PREDEFINEMACROS_TEST(x) DISABLED_##x
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 1df040e06db35e9..d2c0f1cce8afdb4 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1720,6 +1720,12 @@ void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
   OS << "{";
   for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
     if (i) OS << ", ";
+    // TODO: There is duplicated functionality in APValue::printPretty.
+    // Would be good to consolidate the two.
+    if (!Policy.EntireContentsOfLargeArray && i == 10) {
+      OS << "...";
+      break;
+    }
     if (Node->getInit(i))
       PrintExpr(Node->getInit(i));
     else



More information about the cfe-commits mailing list