[clang-tools-extra] [clangd] Add hover support for statement attributes (PR #214318)
Maria Fernanda GuimarĂ£es via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 6 03:50:46 PDT 2026
https://github.com/mafeguimaraes updated https://github.com/llvm/llvm-project/pull/214318
>From e49be6731684044b85c11c3b4893b8cc2f890906 Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Wed, 5 Aug 2026 18:10:16 +0000
Subject: [PATCH 1/2] Add hover support for HLSL statement attributes
---
clang-tools-extra/clangd/Selection.cpp | 8 +++
.../clangd/unittests/HoverTests.cpp | 60 +++++++++++++++++++
2 files changed, 68 insertions(+)
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp
index b79ffc7d5a6e9..41d028cfcf4b5 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -666,6 +666,14 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
bool TraverseAttr(Attr *X) {
return traverseNode(X, [&] { return Base::TraverseAttr(X); });
}
+ bool TraverseAttributedStmt(AttributedStmt *S) {
+ return traverseNode(S, [&] {
+ for (const Attr *A : S->getAttrs())
+ if (!TraverseAttr(const_cast<Attr *>(A)))
+ return false;
+ return TraverseStmt(S->getSubStmt());
+ });
+ }
bool TraverseConceptReference(ConceptReference *X) {
return traverseNode(X, [&] { return Base::TraverseConceptReference(X); });
}
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index e6ad6acc6ea54..4f557ad3162fb 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5411,7 +5411,67 @@ TEST(Hover, HLSLInvalidVectorSwizzleNoCrash) {
auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
EXPECT_FALSE(H);
}
+TEST(Hover, HLSLControlFlowAndLoopHints) {
+ struct {
+ const char *const Code;
+ const std::function<void(HoverInfo &)> ExpectedBuilder;
+ } Cases[] = {{
+ R"hlsl(
+ [numthreads(1, 1, 1)]
+ void main() {
+ [^unroll]
+ for (int i = 0; i < 4; i++) {}
+ }
+ )hlsl",
+ [](HoverInfo &HI) { HI.Name = "unroll"; }},
+ {
+ R"hlsl(
+ [numthreads(1, 1, 1)]
+ void main() {
+ [l^oop]
+ for (int i = 0; i < 4; i++) {}
+ }
+ )hlsl",
+ [](HoverInfo &HI) { HI.Name = "loop"; }},
+ {
+ R"hlsl(
+ [numthreads(1, 1, 1)]
+ void main() {
+ [b^ranch]
+ if (true) {}
+ }
+ )hlsl",
+ [](HoverInfo &HI) { HI.Name = "branch"; }},
+ {
+ R"hlsl(
+ [numthreads(1, 1, 1)]
+ void main() {
+ [f^latten]
+ if (true) {}
+ }
+ )hlsl",
+ [](HoverInfo &HI) { HI.Name = "flatten"; }}};
+
+ for (const auto &Case : Cases) {
+ SCOPED_TRACE(Case.Code);
+ Annotations T(Case.Code);
+ TestTU TU = TestTU::withCode(T.code());
+ configureHLSL(TU);
+ auto AST = TU.build();
+
+ auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+ ASSERT_TRUE(H);
+ HoverInfo Expected;
+ Case.ExpectedBuilder(Expected);
+
+ EXPECT_EQ(H->Name, Expected.Name);
+
+ if (Expected.Name == "unroll" || Expected.Name == "loop") {
+ EXPECT_FALSE(H->Documentation.empty());
+ }
+ }
+}
} // namespace
} // namespace clangd
} // namespace clang
>From 0e4debbb76d8f7b29f2d5d828696a0e1b24cff8d Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Wed, 5 Aug 2026 21:15:34 +0000
Subject: [PATCH 2/2] Add hover tests for C++ statement attributes
---
.../clangd/unittests/HoverTests.cpp | 48 +++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 4f557ad3162fb..4fd7aee16dc34 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5472,6 +5472,54 @@ TEST(Hover, HLSLControlFlowAndLoopHints) {
}
}
}
+
+TEST(Hover, CXXStatementAttributes) {
+ struct {
+ const char *const Code;
+ const char *const Target;
+ const char *const ExpectedName;
+ } Cases[] = {{
+ R"cpp(
+ void foo() {
+ [[likely]] if (true) {}
+ }
+ )cpp",
+ "likely", "likely"},
+ {
+ R"cpp(
+ void foo() {
+ [[unlikely]] if (true) {}
+ }
+ )cpp",
+ "unlikely", "unlikely"},
+ {
+ R"cpp(
+ void foo() {
+ switch (1) {
+ case 1:
+ [[fallthrough]];
+ case 2:
+ break;
+ }
+ }
+ )cpp",
+ "fallthrough", "fallthrough"}};
+
+ for (const auto &Case : Cases) {
+ SCOPED_TRACE(Case.Code);
+ TestTU TU = TestTU::withCode(Case.Code);
+ TU.ExtraArgs.push_back("-std=c++20");
+ auto AST = TU.build();
+
+ llvm::StringRef Code = Case.Code;
+ size_t Offset = Code.find(Case.Target);
+ Position P = offsetToPosition(Code, Offset);
+
+ auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
+ ASSERT_TRUE(H);
+ EXPECT_EQ(H->Name, Case.ExpectedName);
+ }
+}
} // namespace
} // namespace clangd
} // namespace clang
More information about the cfe-commits
mailing list