[clang] [clang-tools-extra] [clangd][HLSL] Fix register attribute source range for hover inside arguments (PR #212881)
Maria Fernanda GuimarĂ£es via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 5 13:48:02 PDT 2026
https://github.com/mafeguimaraes updated https://github.com/llvm/llvm-project/pull/212881
>From 6d2ca90caecb9c64ed3325cf2a0fb56008c05d84 Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Wed, 29 Jul 2026 21:46:49 +0000
Subject: [PATCH] [clangd][HLSL] Fix register attribute source range for hover
inside arguments
Hovering on the slot identifier inside register(t1) (e.g. on t1)
previously produced no tooltip; only hovering on the register keyword
itself worked.
HLSLResourceBindingAttr's SourceRange was zero-width: both the start
and end pointed to the start of the register keyword.
ParseHLSLAnnotations called Attrs.addNew with a single SourceLocation
instead of a full SourceRange. Since clangd's SelectionTree only
matches when the cursor falls inside an attribute's range, a
zero-width range never matched positions inside the argument.
Capture the closing ')' location before it's consumed in the
AT_HLSLResourceBinding case, and pass a full SourceRange (from the
attribute start to the closing paren) to addNew.
Fixes #212749
---
.../clangd/unittests/HoverTests.cpp | 19 +++++++++++++++++++
clang/lib/Parse/ParseHLSL.cpp | 5 ++++-
.../test/AST/HLSL/resource_binding_attr.hlsl | 7 +++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index e6ad6acc6ea54..02ce48c6dca95 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5412,6 +5412,25 @@ TEST(Hover, HLSLInvalidVectorSwizzleNoCrash) {
EXPECT_FALSE(H);
}
+TEST(Hover, HLSLRegisterAttributeRange) {
+ Annotations T(R"hlsl(
+ Texture2D tex : [[^register]]([[^t1]]);
+ )hlsl");
+
+ TestTU TU = TestTU::withCode(T.code());
+ configureHLSL(TU);
+
+ auto AST = TU.build();
+
+ for (const auto &P : T.points()) {
+ auto H = getHover(AST, P, format::getLLVMStyle(), nullptr);
+
+ ASSERT_TRUE(H);
+ EXPECT_EQ(H->Name, "register");
+ EXPECT_FALSE(H->Documentation.empty());
+ }
+}
+
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp
index c727ee3a1f1a6..24d0df1144055 100644
--- a/clang/lib/Parse/ParseHLSL.cpp
+++ b/clang/lib/Parse/ParseHLSL.cpp
@@ -185,6 +185,7 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
if (EndLoc)
*EndLoc = Tok.getLocation();
+ SourceLocation AttrEndLoc = Loc;
ArgsVector ArgExprs;
switch (AttrKind) {
case ParsedAttr::AT_HLSLResourceBinding: {
@@ -227,6 +228,7 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
fixSeparateAttrArgAndNumber(SpaceStr, SpaceLoc, Tok, ArgExprs, *this,
Actions.Context, PP);
}
+ AttrEndLoc = Tok.getLocation(); // location of the closing ')'
if (ExpectAndConsume(tok::r_paren, diag::err_expected)) {
SkipUntil(tok::r_paren, StopAtSemi); // skip through )
return;
@@ -337,6 +339,7 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
break;
}
- Attrs.addNew(II, Loc, AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(),
+ Attrs.addNew(II, SourceRange(Loc, AttrEndLoc), AttributeScopeInfo(),
+ ArgExprs.data(), ArgExprs.size(),
ParsedAttr::Form::HLSLAnnotation());
}
diff --git a/clang/test/AST/HLSL/resource_binding_attr.hlsl b/clang/test/AST/HLSL/resource_binding_attr.hlsl
index 2cd2b96bc41b5..bd7ecf83f4125 100644
--- a/clang/test/AST/HLSL/resource_binding_attr.hlsl
+++ b/clang/test/AST/HLSL/resource_binding_attr.hlsl
@@ -98,6 +98,13 @@ StructuredBuffer<float> SB[10];
[[vk::binding(2)]]
StructuredBuffer<float> SB2[10];
+// Regression test: the register attribute's SourceRange should span the
+// full `register(...)` construct (not just the `register` keyword), so
+// that clangd hover works when the cursor is inside the argument list.
+// CHECK: VarDecl {{.*}} rangeTest 'RWBuffer<float>':'hlsl::RWBuffer<float>'
+// CHECK: HLSLResourceBindingAttr {{.*}} "u7" "space0"
+RWBuffer<float> rangeTest : register(u7);
+
// $Globals should have implicit binding attribute added by SemaHLSL
// CHECK: HLSLBufferDecl {{.*}} implicit cbuffer $Globals
// CHECK: HLSLResourceBindingAttr {{.*}} Implicit "" "0"
More information about the cfe-commits
mailing list