[clang-tools-extra] a0cc776 - [clangd] Add Hover.MacroContentsLimit config option (#155105)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 27 21:19:13 PDT 2025
Author: Jaagup Averin
Date: 2025-08-28T00:19:08-04:00
New Revision: a0cc776732980e792b201e3848c1049dfc3b1836
URL: https://github.com/llvm/llvm-project/commit/a0cc776732980e792b201e3848c1049dfc3b1836
DIFF: https://github.com/llvm/llvm-project/commit/a0cc776732980e792b201e3848c1049dfc3b1836.diff
LOG: [clangd] Add Hover.MacroContentsLimit config option (#155105)
Currently macro expansions are hard capped at 2048. This PR adds
the `Hover.MacroContentsLimit` config option for overriding the default.
Fixes https://github.com/llvm/llvm-project/issues/153355
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/Hover.cpp
clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/Config.h b/clang-tools-extra/clangd/Config.h
index 2e3e0a431ab1f..01997cee08515 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -174,6 +174,9 @@ struct Config {
struct {
/// Whether hover show a.k.a type.
bool ShowAKA = true;
+ /// Limit the number of characters returned when hovering a macro;
+ /// 0 is no limit.
+ uint32_t MacroContentsLimit = 2048;
} Hover;
struct {
diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp b/clang-tools-extra/clangd/ConfigCompile.cpp
index 5dda6dd8bf712..962a48bcb7671 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -727,6 +727,12 @@ struct FragmentCompiler {
C.Hover.ShowAKA = ShowAKA;
});
}
+ if (F.MacroContentsLimit) {
+ Out.Apply.push_back(
+ [Limit(**F.MacroContentsLimit)](const Params &, Config &C) {
+ C.Hover.MacroContentsLimit = Limit;
+ });
+ }
}
void compile(Fragment::InlayHintsBlock &&F) {
diff --git a/clang-tools-extra/clangd/ConfigFragment.h b/clang-tools-extra/clangd/ConfigFragment.h
index 0f11f37e14698..2afeb36574b21 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -361,6 +361,8 @@ struct Fragment {
struct HoverBlock {
/// Whether hover show a.k.a type.
std::optional<Located<bool>> ShowAKA;
+ /// Limit the number of characters returned when hovering a macro.
+ std::optional<Located<uint32_t>> MacroContentsLimit;
};
HoverBlock Hover;
diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp b/clang-tools-extra/clangd/ConfigYAML.cpp
index 289b7e8d1c49d..392cf19b05a55 100644
--- a/clang-tools-extra/clangd/ConfigYAML.cpp
+++ b/clang-tools-extra/clangd/ConfigYAML.cpp
@@ -264,6 +264,10 @@ class Parser {
if (auto ShowAKA = boolValue(N, "ShowAKA"))
F.ShowAKA = *ShowAKA;
});
+ Dict.handle("MacroContentsLimit", [&](Node &N) {
+ if (auto MacroContentsLimit = uint32Value(N, "MacroContentsLimit"))
+ F.MacroContentsLimit = *MacroContentsLimit;
+ });
Dict.parse(N);
}
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index 30c70ac02205b..9eec322fe5963 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -794,7 +794,9 @@ HoverInfo getHoverContents(const DefinedMacro &Macro, const syntax::Token &Tok,
for (const auto &ExpandedTok : Expansion->Expanded) {
ExpansionText += ExpandedTok.text(SM);
ExpansionText += " ";
- if (ExpansionText.size() > 2048) {
+ const Config &Cfg = Config::current();
+ const size_t Limit = static_cast<size_t>(Cfg.Hover.MacroContentsLimit);
+ if (Limit && ExpansionText.size() > Limit) {
ExpansionText.clear();
break;
}
diff --git a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
index d71b8d5f9302a..d94e706ca05de 100644
--- a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
@@ -230,17 +230,19 @@ TEST(ParseYAML, CodePatterns) {
EXPECT_THAT(Results[0].Completion.CodePatterns, llvm::ValueIs(val("None")));
}
-TEST(ParseYAML, ShowAKA) {
+TEST(ParseYAML, Hover) {
CapturedDiags Diags;
Annotations YAML(R"yaml(
Hover:
ShowAKA: True
+ MacroContentsLimit: 4096
)yaml");
auto Results =
Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback());
ASSERT_THAT(Diags.Diagnostics, IsEmpty());
ASSERT_EQ(Results.size(), 1u);
EXPECT_THAT(Results[0].Hover.ShowAKA, llvm::ValueIs(val(true)));
+ EXPECT_THAT(Results[0].Hover.MacroContentsLimit, llvm::ValueIs(val(4096U)));
}
TEST(ParseYAML, InlayHints) {
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 537c061a1b04c..198102bbc9c29 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -4767,6 +4767,48 @@ constexpr u64 pow_with_mod(u64 a, u64 b, u64 p) {
EXPECT_TRUE(H->Type);
}
+TEST(Hover, HoverMacroContentsLimit) {
+ const char *const Code =
+ R"cpp(
+ #define C(A) A##A // Concatenate
+ #define E(A) C(A) // Expand
+ #define Z0032 00000000000000000000000000000000
+ #define Z0064 E(Z0032)
+ #define Z0128 E(Z0064)
+ #define Z0256 E(Z0128)
+ #define Z0512 E(Z0256)
+ #define Z1024 E(Z0512)
+ #define Z2048 E(Z1024)
+ #define Z4096 E(Z2048) // 4096 zeroes
+ int main() { return [[^Z4096]]; }
+ )cpp";
+
+ struct {
+ uint32_t MacroContentsLimit;
+ const std::string ExpectedDefinition;
+ } Cases[] = {
+ // With a limit of 2048, the macro expansion should get dropped.
+ {2048, "#define Z4096 E(Z2048)"},
+ // With a limit of 8192, the macro expansion should be fully expanded.
+ {8192, std::string("#define Z4096 E(Z2048)\n\n") +
+ std::string("// Expands to\n") + std::string(4096, '0')},
+ };
+ for (const auto &Case : Cases) {
+ SCOPED_TRACE(Code);
+
+ Annotations T(Code);
+ TestTU TU = TestTU::withCode(T.code());
+ auto AST = TU.build();
+ Config Cfg;
+ Cfg.Hover.MacroContentsLimit = Case.MacroContentsLimit;
+ WithContextValue WithCfg(Config::Key, std::move(Cfg));
+ auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+ ASSERT_TRUE(H);
+
+ EXPECT_EQ(H->Definition, Case.ExpectedDefinition);
+ }
+};
+
TEST(Hover, FunctionParameters) {
struct {
const char *const Code;
More information about the cfe-commits
mailing list