[clang] [clang-tools-extra] [clangd][HLSL] Fix hover type for out/inout parameters (PR #214883)
Maria Fernanda GuimarĂ£es via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 18 16:57:12 PDT 2026
https://github.com/mafeguimaraes updated https://github.com/llvm/llvm-project/pull/214883
>From b6e8506f42ad4e352206486684da87d48e30ccbe Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Fri, 7 Aug 2026 13:55:59 +0000
Subject: [PATCH 1/5] Add getHLSLParamTypeAsWritten to ParmVarDecl
---
clang/include/clang/AST/Decl.h | 2 ++
clang/lib/AST/Decl.cpp | 14 ++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 0a6f256afa2cc..388db61a9d38a 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -1971,6 +1971,8 @@ class ParmVarDecl : public VarDecl {
QualType getOriginalType() const;
+ std::string getHLSLParamTypeAsWritten(const PrintingPolicy &Policy) const;
+
/// Sets the function declaration that owns this
/// ParmVarDecl. Since ParmVarDecls are often created before the
/// FunctionDecls that own them, this routine is required to update
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 5a76a726cd1f1..31db3be8ea6f0 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2950,6 +2950,20 @@ QualType ParmVarDecl::getOriginalType() const {
return T;
}
+std::string ParmVarDecl::getHLSLParamTypeAsWritten(const PrintingPolicy &Policy) const {
+ if (const auto *Mod = getAttr<HLSLParamModifierAttr>()) {
+ QualType BaseType = getType().getNonReferenceType();
+ std::string BaseHLSLType = BaseType.getAsString(Policy);
+
+ if (Mod->isOut())
+ return "out " + BaseHLSLType;
+ if (Mod->isInOut())
+ return "inout " + BaseHLSLType;
+ }
+
+ return getType().getAsString(Policy);
+}
+
ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
return new (C, ID)
ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(),
>From e5d2fa7a4b1dc46394f0c11f7d38408d604ee4fe Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Fri, 7 Aug 2026 15:59:53 +0000
Subject: [PATCH 2/5] Use getHLSLParamTypeAsWritten for parameter hover
---
clang-tools-extra/clangd/Hover.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index a2f8b6418833d..f49475fdad1ad 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -376,8 +376,8 @@ const Expr *getDefaultArg(const ParmVarDecl *PVD) {
HoverInfo::Param toHoverInfoParam(const ParmVarDecl *PVD,
const PrintingPolicy &PP) {
HoverInfo::Param Out;
- Out.Type = printType(PVD->getType(), PVD->getASTContext(), PP);
- if (!PVD->getName().empty())
+ Out.Type = HoverInfo::PrintedType(
+ PVD->getHLSLParamTypeAsWritten(PP).c_str()); if (!PVD->getName().empty())
Out.Name = PVD->getNameAsString();
if (const Expr *DefArg = getDefaultArg(PVD)) {
Out.Default.emplace();
@@ -697,6 +697,9 @@ HoverInfo getHoverContents(const NamedDecl *D, const PrintingPolicy &PP,
// Fill in types and params.
if (const FunctionDecl *FD = getUnderlyingFunction(D))
fillFunctionTypeAndParams(HI, D, FD, PP);
+ else if (const auto *PVD = dyn_cast<ParmVarDecl>(D))
+ HI.Type = HoverInfo::PrintedType(
+ PVD->getHLSLParamTypeAsWritten(PP).c_str());
else if (const auto *VD = dyn_cast<ValueDecl>(D))
HI.Type = printType(VD->getType(), Ctx, PP);
else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
@@ -721,6 +724,9 @@ HoverInfo getHoverContents(const NamedDecl *D, const PrintingPolicy &PP,
}
HI.Definition = printDefinition(D, PP, TB);
+ if (const auto *PVD = dyn_cast<ParmVarDecl>(D))
+ HI.Definition =
+ PVD->getHLSLParamTypeAsWritten(PP) + " " + PVD->getNameAsString();
return HI;
}
>From cfe8bd0c50cc548d8ea36325a1a39003e33d7051 Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Fri, 7 Aug 2026 23:16:17 +0000
Subject: [PATCH 3/5] Add hover tests for out/inout parameters
---
.../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 02ce48c6dca95..dabe68a0f1c81 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5431,6 +5431,54 @@ TEST(Hover, HLSLRegisterAttributeRange) {
}
}
+TEST(Hover, HLSLParamModifiers) {
+ struct {
+ const char *const Code;
+ const char *const ExpectedType;
+ } Cases[] = {
+ {
+ R"hlsl(
+ void main(out float ^result) {}
+ )hlsl",
+ "out float"
+ },
+ {
+ R"hlsl(
+ void main(out float result) {
+ ^result = 1.0;
+ }
+ )hlsl",
+ "out float"
+ },
+ {
+ R"hlsl(
+ void main(inout float ^result) {}
+ )hlsl",
+ "inout float"
+ },
+ {
+ R"hlsl(
+ void main(inout float result) {
+ ^result = 1.0;
+ }
+ )hlsl",
+ "inout float"
+ }
+ };
+
+ 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);
+ ASSERT_TRUE(H->Type) << "Hover should have returned a type!";
+ EXPECT_EQ(H->Type->Type, Case.ExpectedType);
+ }
+}
+
} // namespace
} // namespace clangd
} // namespace clang
>From 84e464bfde5d0e2b81972cfab8d9a83d7cfcdb19 Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Fri, 7 Aug 2026 23:48:40 +0000
Subject: [PATCH 4/5] Apply clang-format
---
clang-tools-extra/clangd/Hover.cpp | 29 ++++++++++++------
.../clangd/unittests/HoverTests.cpp | 30 ++++++++-----------
clang/lib/AST/Decl.cpp | 7 +++--
3 files changed, 36 insertions(+), 30 deletions(-)
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index f49475fdad1ad..1c7697b858948 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -376,8 +376,14 @@ const Expr *getDefaultArg(const ParmVarDecl *PVD) {
HoverInfo::Param toHoverInfoParam(const ParmVarDecl *PVD,
const PrintingPolicy &PP) {
HoverInfo::Param Out;
- Out.Type = HoverInfo::PrintedType(
- PVD->getHLSLParamTypeAsWritten(PP).c_str()); if (!PVD->getName().empty())
+ if (PVD->getASTContext().getLangOpts().HLSL) {
+ Out.Type =
+ HoverInfo::PrintedType(PVD->getHLSLParamTypeAsWritten(PP).c_str());
+ } else {
+ Out.Type = printType(PVD->getType(), PVD->getASTContext(), PP);
+ }
+
+ if (!PVD->getName().empty())
Out.Name = PVD->getNameAsString();
if (const Expr *DefArg = getDefaultArg(PVD)) {
Out.Default.emplace();
@@ -697,10 +703,13 @@ HoverInfo getHoverContents(const NamedDecl *D, const PrintingPolicy &PP,
// Fill in types and params.
if (const FunctionDecl *FD = getUnderlyingFunction(D))
fillFunctionTypeAndParams(HI, D, FD, PP);
- else if (const auto *PVD = dyn_cast<ParmVarDecl>(D))
- HI.Type = HoverInfo::PrintedType(
- PVD->getHLSLParamTypeAsWritten(PP).c_str());
- else if (const auto *VD = dyn_cast<ValueDecl>(D))
+ else if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
+ if (PVD->getASTContext().getLangOpts().HLSL)
+ HI.Type =
+ HoverInfo::PrintedType(PVD->getHLSLParamTypeAsWritten(PP).c_str());
+ else
+ HI.Type = printType(PVD->getType(), Ctx, PP);
+ } else if (const auto *VD = dyn_cast<ValueDecl>(D))
HI.Type = printType(VD->getType(), Ctx, PP);
else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
HI.Type = TTP->wasDeclaredWithTypename() ? "typename" : "class";
@@ -724,9 +733,11 @@ HoverInfo getHoverContents(const NamedDecl *D, const PrintingPolicy &PP,
}
HI.Definition = printDefinition(D, PP, TB);
- if (const auto *PVD = dyn_cast<ParmVarDecl>(D))
- HI.Definition =
- PVD->getHLSLParamTypeAsWritten(PP) + " " + PVD->getNameAsString();
+ if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
+ if (PVD->getASTContext().getLangOpts().HLSL)
+ HI.Definition =
+ PVD->getHLSLParamTypeAsWritten(PP) + " " + PVD->getNameAsString();
+ }
return HI;
}
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index dabe68a0f1c81..2dbbeb4fd88a9 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5435,36 +5435,30 @@ TEST(Hover, HLSLParamModifiers) {
struct {
const char *const Code;
const char *const ExpectedType;
- } Cases[] = {
- {
- R"hlsl(
+ } Cases[] = {{
+ R"hlsl(
void main(out float ^result) {}
)hlsl",
- "out float"
- },
- {
- R"hlsl(
+ "out float"},
+ {
+ R"hlsl(
void main(out float result) {
^result = 1.0;
}
)hlsl",
- "out float"
- },
- {
- R"hlsl(
+ "out float"},
+ {
+ R"hlsl(
void main(inout float ^result) {}
)hlsl",
- "inout float"
- },
- {
- R"hlsl(
+ "inout float"},
+ {
+ R"hlsl(
void main(inout float result) {
^result = 1.0;
}
)hlsl",
- "inout float"
- }
- };
+ "inout float"}};
for (const auto &Case : Cases) {
SCOPED_TRACE(Case.Code);
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 31db3be8ea6f0..01589cff1147f 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2950,17 +2950,18 @@ QualType ParmVarDecl::getOriginalType() const {
return T;
}
-std::string ParmVarDecl::getHLSLParamTypeAsWritten(const PrintingPolicy &Policy) const {
+std::string
+ParmVarDecl::getHLSLParamTypeAsWritten(const PrintingPolicy &Policy) const {
if (const auto *Mod = getAttr<HLSLParamModifierAttr>()) {
QualType BaseType = getType().getNonReferenceType();
std::string BaseHLSLType = BaseType.getAsString(Policy);
-
+
if (Mod->isOut())
return "out " + BaseHLSLType;
if (Mod->isInOut())
return "inout " + BaseHLSLType;
}
-
+
return getType().getAsString(Policy);
}
>From 263a9486711199ebd49f92068981211ac97a3a59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maria=20Fernanda=20Guimar=C3=A3es?= <mariafefe201 at gmail.com>
Date: Tue, 18 Aug 2026 20:57:01 -0300
Subject: [PATCH 5/5] Update clang-tools-extra/clangd/Hover.cpp
Co-authored-by: Ashley Coleman <ascoleman at microsoft.com>
---
clang-tools-extra/clangd/Hover.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index 1c7697b858948..3afdf68bdcc84 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -376,12 +376,11 @@ const Expr *getDefaultArg(const ParmVarDecl *PVD) {
HoverInfo::Param toHoverInfoParam(const ParmVarDecl *PVD,
const PrintingPolicy &PP) {
HoverInfo::Param Out;
- if (PVD->getASTContext().getLangOpts().HLSL) {
+ if (PVD->getASTContext().getLangOpts().HLSL)
Out.Type =
HoverInfo::PrintedType(PVD->getHLSLParamTypeAsWritten(PP).c_str());
- } else {
+ else
Out.Type = printType(PVD->getType(), PVD->getASTContext(), PP);
- }
if (!PVD->getName().empty())
Out.Name = PVD->getNameAsString();
More information about the cfe-commits
mailing list