[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
Mon Aug 3 11:55:01 PDT 2026
https://github.com/mafeguimaraes updated https://github.com/llvm/llvm-project/pull/212881
>From 5999ce77963716932030fd6a4400673b903c3c04 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 | 24 +++++++++++++++++++
clang/lib/Parse/ParseHLSL.cpp | 5 +++-
.../test/AST/HLSL/resource_binding_attr.hlsl | 7 ++++++
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index e0773708df0eb..bd8b7dbc1eb43 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5311,6 +5311,30 @@ TEST(Hover, FunctionParameters) {
}
}
+TEST(Hover, HLSLRegisterAttributeRange) {
+ Annotations T(R"hlsl(
+ Texture2D tex : [[^register]]([[^t1]]);
+ )hlsl");
+
+ TestTU TU = TestTU::withCode(T.code());
+ TU.Filename = "TestTU.hlsl";
+ TU.ExtraArgs = {
+ "-x",
+ "hlsl",
+ "--target=dxil-pc-shadermodel6.3-library",
+ };
+
+ 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..637691f04b482 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 {{.*}} <col:29, col:41> "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