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 <[email protected]> Date: Wed, 5 Aug 2026 18:10:16 +0000 Subject: [PATCH 1/3] 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 <[email protected]> Date: Wed, 5 Aug 2026 21:15:34 +0000 Subject: [PATCH 2/3] 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 From 9ecdb074d9752247390834d388929b45e622fde5 Mon Sep 17 00:00:00 2001 From: Maria Fernanda Guimaraes <[email protected]> Date: Fri, 7 Aug 2026 13:01:13 +0000 Subject: [PATCH 3/3] Refactor C++ statement attributes tests to use custom Annotation markers --- .../clangd/unittests/HoverTests.cpp | 167 ++++++++---------- 1 file changed, 70 insertions(+), 97 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index 4fd7aee16dc34..16921e18478e3 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -5411,115 +5411,88 @@ TEST(Hover, HLSLInvalidVectorSwizzleNoCrash) { auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr); EXPECT_FALSE(H); } -TEST(Hover, HLSLControlFlowAndLoopHints) { + +TEST(Hover, AttributedStmt) { 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"; }}}; - + 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 T(Case.Code, + Annotations::Markers().setRangeBegin("{{").setRangeEnd("}}")); TestTU TU = TestTU::withCode(T.code()); - configureHLSL(TU); + 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); - - HoverInfo Expected; - Case.ExpectedBuilder(Expected); - - EXPECT_EQ(H->Name, Expected.Name); - - if (Expected.Name == "unroll" || Expected.Name == "loop") { + EXPECT_EQ(H->Name, Case.ExpectedName); + if (Case.ExpectDocumentation) { EXPECT_FALSE(H->Documentation.empty()); } } } - -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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
