[clang-tools-extra] b79317f - [clangd] Add hover support for statement attributes (#214318)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 14 07:58:29 PDT 2026
Author: Maria Fernanda GuimarĂ£es
Date: 2026-08-14T22:58:24+08:00
New Revision: b79317f9877d805a5091b26dd1f2eb795b5aca05
URL: https://github.com/llvm/llvm-project/commit/b79317f9877d805a5091b26dd1f2eb795b5aca05
DIFF: https://github.com/llvm/llvm-project/commit/b79317f9877d805a5091b26dd1f2eb795b5aca05.diff
LOG: [clangd] Add hover support for statement attributes (#214318)
Hovering over `[unroll]`, `[loop]`, `[branch]`, or `[flatten]` should
display the attribute name and documentation about its effect on GPU
shader execution.
This patch extends clangd's `SelectionTree` to traverse attributes
attached to `AttributedStmt` nodes before visiting the underlying
statement.
Fixes #214067
Added:
Modified:
clang-tools-extra/clangd/Selection.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp
Removed:
################################################################################
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 02ce48c6dca95..d355118f30761 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5412,6 +5412,87 @@ TEST(Hover, HLSLInvalidVectorSwizzleNoCrash) {
EXPECT_FALSE(H);
}
+TEST(Hover, AttributedStmt) {
+ struct {
+ const char *const Code;
+ const char *const ExpectedName;
+ bool IsHLSL;
+ bool ExpectDocumentation;
+ } Cases[] = {
+ {R"hlsl(
+ [numthreads(1, 1, 1)]
+ void main() {
+ [^unroll]
+ for (int i = 0; i < 4; i++) {}
+ }
+ )hlsl",
+ "unroll", /*IsHLSL=*/true, /*ExpectDocumentation=*/true},
+ {R"hlsl(
+ [numthreads(1, 1, 1)]
+ void main() {
+ [l^oop]
+ for (int i = 0; i < 4; i++) {}
+ }
+ )hlsl",
+ "loop", /*IsHLSL=*/true, /*ExpectDocumentation=*/true},
+ {R"hlsl(
+ [numthreads(1, 1, 1)]
+ void main() {
+ [b^ranch]
+ if (true) {}
+ }
+ )hlsl",
+ "branch", /*IsHLSL=*/true, /*ExpectDocumentation=*/false},
+ {R"hlsl(
+ [numthreads(1, 1, 1)]
+ void main() {
+ [f^latten]
+ if (true) {}
+ }
+ )hlsl",
+ "flatten", /*IsHLSL=*/true, /*ExpectDocumentation=*/false},
+ {R"cpp(
+ void foo() {
+ [[^likely]] if (true) {}
+ }
+ )cpp",
+ "likely", /*IsHLSL=*/false, /*ExpectDocumentation=*/false},
+ {R"cpp(
+ void foo() {
+ [[^unlikely]] if (true) {}
+ }
+ )cpp",
+ "unlikely", /*IsHLSL=*/false, /*ExpectDocumentation=*/false},
+ {R"cpp(
+ void foo() {
+ switch (1) {
+ case 1:
+ [[^fallthrough]];
+ case 2:
+ break;
+ }
+ }
+ )cpp",
+ "fallthrough", /*IsHLSL=*/false, /*ExpectDocumentation=*/false},
+ };
+ for (const auto &Case : Cases) {
+ SCOPED_TRACE(Case.Code);
+ Annotations T(Case.Code,
+ Annotations::Markers().setRangeBegin("{{").setRangeEnd("}}"));
+ TestTU TU = TestTU::withCode(T.code());
+ if (Case.IsHLSL)
+ configureHLSL(TU);
+ else
+ TU.ExtraArgs.push_back("-std=c++20");
+ auto AST = TU.build();
+ auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+ ASSERT_TRUE(H);
+ EXPECT_EQ(H->Name, Case.ExpectedName);
+ if (Case.ExpectDocumentation) {
+ EXPECT_FALSE(H->Documentation.empty());
+ }
+ }
+}
TEST(Hover, HLSLRegisterAttributeRange) {
Annotations T(R"hlsl(
Texture2D tex : [[^register]]([[^t1]]);
More information about the cfe-commits
mailing list