[clang] [clang-tools-extra] [clangd][HLSL] Fix hover for semantic annotations showing "(No spelling)" (PR #217725)
Maria Fernanda GuimarĂ£es via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 30 04:16:21 PDT 2026
https://github.com/mafeguimaraes updated https://github.com/llvm/llvm-project/pull/217725
>From e7efde02c9c0828765384c28256ca096e766f434 Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Wed, 19 Aug 2026 20:50:19 +0000
Subject: [PATCH 1/8] Add hlsl hover semantic annotations
---
clang-tools-extra/clangd/Hover.cpp | 8 ++++++++
clang/include/clang/Basic/Attr.td | 10 +++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index a2f8b6418833d..20c3b52f1daea 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -1013,6 +1013,14 @@ std::optional<HoverInfo> getHoverContents(const SelectionTree::Node *N,
// Generates hover info for attributes.
std::optional<HoverInfo> getHoverContents(const Attr *A, ParsedAST &AST) {
HoverInfo HI;
+ if (const auto *SA = llvm::dyn_cast<HLSLUnparsedSemanticAttr>(A)) {
+ std::string Name = A->getAttrName()->getName().str();
+ if (SA->getExplicitIndex())
+ Name += std::to_string(SA->getIndex());
+ HI.Name = Name;
+ HI.Definition = "[" + Name + "]";
+ return HI;
+ }
HI.Name = A->getSpelling();
if (A->hasScope())
HI.LocalScope = A->getScopeName()->getName().str();
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 252b53e25e5c8..89a4723df1760 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -5164,7 +5164,15 @@ class HLSLSemanticBaseAttr : HLSLAnnotationAttr {
}
def HLSLParsedSemantic : HLSLSemanticBaseAttr {
- let Spellings = [];
+ let Spellings = [
+ Microsoft<"SV_Position">,
+ Microsoft<"SV_Target">,
+ Microsoft<"SV_DispatchThreadID">,
+ Microsoft<"SV_GroupID">,
+ Microsoft<"SV_GroupIndex">,
+ Microsoft<"SV_GroupThreadID">,
+ Microsoft<"SV_VertexID">
+ ];
let Subjects = SubjectList<[ParmVar, Field, Function]>;
let LangOpts = [HLSL];
let Documentation = [InternalOnly];
>From d790aa7f36d48d02e2003b9f9a1875d0d21ca174 Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Thu, 20 Aug 2026 11:14:36 +0000
Subject: [PATCH 2/8] Add support to AT_HLSLParsedSemantic
---
clang/lib/Parse/ParseHLSL.cpp | 26 +++++++++++++++++++++-----
clang/lib/Sema/SemaDeclAttr.cpp | 3 +++
clang/lib/Sema/SemaHLSL.cpp | 9 +++++----
3 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp
index 24d0df1144055..338104bc87545 100644
--- a/clang/lib/Parse/ParseHLSL.cpp
+++ b/clang/lib/Parse/ParseHLSL.cpp
@@ -176,11 +176,14 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
}
ParsedAttr::Kind AttrKind =
- ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_HLSLAnnotation);
+ ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_Microsoft);
+ if (AttrKind != ParsedAttr::AT_HLSLParsedSemantic)
+ AttrKind =
+ ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_HLSLAnnotation);
Parser::ParsedSemantic Semantic;
- if (AttrKind == ParsedAttr::AT_HLSLUnparsedSemantic)
+ if (AttrKind == ParsedAttr::AT_HLSLUnparsedSemantic ||
+ AttrKind == ParsedAttr::AT_HLSLParsedSemantic)
Semantic = ParseHLSLSemantic();
-
SourceLocation Loc = ConsumeToken();
if (EndLoc)
*EndLoc = Tok.getLocation();
@@ -332,6 +335,17 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
II = PP.getIdentifierInfo(Semantic.Name);
break;
}
+ case ParsedAttr::AT_HLSLParsedSemantic: {
+ ASTContext &Ctx = Actions.getASTContext();
+ ArgExprs.push_back(IntegerLiteral::Create(
+ Ctx, llvm::APInt(Ctx.getTypeSize(Ctx.IntTy), Semantic.Index),
+ Ctx.IntTy, SourceLocation()));
+ ArgExprs.push_back(IntegerLiteral::Create(
+ Ctx, llvm::APInt(1, Semantic.Explicit), Ctx.BoolTy,
+ SourceLocation()));
+ II = PP.getIdentifierInfo(Semantic.Name);
+ break;
+}
case ParsedAttr::UnknownAttribute: // FIXME: maybe this is obsolete?
break;
default:
@@ -339,7 +353,9 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
break;
}
+ ParsedAttr::Form Form = (AttrKind == ParsedAttr::AT_HLSLParsedSemantic)
+ ? ParsedAttr::Form::Microsoft()
+ : ParsedAttr::Form::HLSLAnnotation();
Attrs.addNew(II, SourceRange(Loc, AttrEndLoc), AttributeScopeInfo(),
- ArgExprs.data(), ArgExprs.size(),
- ParsedAttr::Form::HLSLAnnotation());
+ ArgExprs.data(), ArgExprs.size(), Form);
}
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index a61fc54ade757..508f31a72f352 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -8288,6 +8288,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_HLSLUnparsedSemantic:
S.HLSL().handleSemanticAttr(D, AL);
break;
+ case ParsedAttr::AT_HLSLParsedSemantic:
+ S.HLSL().handleSemanticAttr(D, AL);
+ break;
case ParsedAttr::AT_HLSLVkLocation:
S.HLSL().handleVkLocationAttr(D, AL);
break;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 184339044e5bf..81b91b78ee321 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2018,11 +2018,12 @@ void SemaHLSL::handleSemanticAttr(Decl *D, const ParsedAttr &AL) {
assert(IndexValue > 0 ? ExplicitIndex : true);
std::optional<unsigned> Index =
ExplicitIndex ? std::optional<unsigned>(IndexValue) : std::nullopt;
-
- if (AL.getAttrName()->getName().starts_with_insensitive("SV_"))
+ if (AL.getKind() == ParsedAttr::AT_HLSLParsedSemantic) {
diagnoseSystemSemanticAttr(D, AL, Index);
- else
- D->addAttr(createSemanticAttr<HLSLParsedSemanticAttr>(AL, Index));
+ } else {
+ D->addAttr(HLSLUnparsedSemanticAttr::Create(
+ SemaRef.getASTContext(), IndexValue, ExplicitIndex, AL));
+ }
}
void SemaHLSL::handlePackOffsetAttr(Decl *D, const ParsedAttr &AL) {
>From 009f22c10879a10ed8d8b60db9f5d2855ff1437e Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Thu, 20 Aug 2026 17:52:08 +0000
Subject: [PATCH 3/8] Add explicit spellings for semantic annotations and hover
tests
---
.../clangd/unittests/HoverTests.cpp | 63 +++++++++++++++++++
clang/lib/Parse/ParseHLSL.cpp | 16 +++--
2 files changed, 73 insertions(+), 6 deletions(-)
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index d355118f30761..2676e4c7db280 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5512,6 +5512,69 @@ TEST(Hover, HLSLRegisterAttributeRange) {
}
}
+TEST(Hover, HLSLSemanticAnnotations) {
+ struct {
+ const char *const Code;
+ const char *const ExpectedName;
+ const char *const ExpectedDefinition;
+ } Cases[] = {
+ {R"hlsl(
+ typedef float float4 __attribute__((ext_vector_type(4)));
+ float4 main(float4 pos : ^SV_Position) : SV_Target {
+ return pos;
+ }
+ )hlsl",
+ "SV_Position", "[SV_Position(\"SV_Position\", 0)]"},
+ {R"hlsl(
+ typedef float float4 __attribute__((ext_vector_type(4)));
+ float4 main(float4 pos : SV_Position) : ^SV_Target {
+ return pos;
+ }
+ )hlsl",
+ "SV_Target", "[SV_Target(\"SV_Target\", 0)]"},
+ {R"hlsl(
+ typedef float float4 __attribute__((ext_vector_type(4)));
+ float4 main(float4 pos : SV_Position) : ^SV_Target1 {
+ return pos;
+ }
+ )hlsl",
+ "SV_Target", "[SV_Target(\"SV_Target\", 1)]"},
+ {R"hlsl(
+ typedef float float4 __attribute__((ext_vector_type(4)));
+ float4 main(float4 uv : ^TEXCOORD0) : SV_Target {
+ return uv;
+ }
+ )hlsl",
+ "TEXCOORD0", "[TEXCOORD0]"},
+ {R"hlsl(
+ typedef float float4 __attribute__((ext_vector_type(4)));
+ float4 main(float4 uv : ^TEXCOORD) : SV_Target {
+ return uv;
+ }
+ )hlsl",
+ "TEXCOORD", "[TEXCOORD]"},
+ };
+
+ 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) << "Hover should have been returned for "
+ << Case.ExpectedName;
+ EXPECT_EQ(H->Name, Case.ExpectedName);
+ EXPECT_EQ(H->Definition, Case.ExpectedDefinition);
+
+ if (llvm::StringRef(Case.ExpectedDefinition).contains("TEXCOORD")) {
+ EXPECT_EQ(H->Definition.find("\""), std::string::npos)
+ << "Definition leaked internal semantic arguments: "
+ << H->Definition;
+ }
+ }
+}
+
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp
index 338104bc87545..cc1f3239d814d 100644
--- a/clang/lib/Parse/ParseHLSL.cpp
+++ b/clang/lib/Parse/ParseHLSL.cpp
@@ -175,16 +175,20 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
return;
}
+ IdentifierInfo *SemanticII = II;
+ Parser::ParsedSemantic Semantic;
+ if (Tok.is(tok::identifier)) {
+ Semantic = ParseHLSLSemantic();
+ SemanticII = PP.getIdentifierInfo(Semantic.Name);
+ }
+
ParsedAttr::Kind AttrKind =
- ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_Microsoft);
+ ParsedAttr::getParsedKind(SemanticII, nullptr, ParsedAttr::AS_Microsoft);
if (AttrKind != ParsedAttr::AT_HLSLParsedSemantic)
AttrKind =
ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_HLSLAnnotation);
- Parser::ParsedSemantic Semantic;
- if (AttrKind == ParsedAttr::AT_HLSLUnparsedSemantic ||
- AttrKind == ParsedAttr::AT_HLSLParsedSemantic)
- Semantic = ParseHLSLSemantic();
- SourceLocation Loc = ConsumeToken();
+
+SourceLocation Loc = ConsumeToken();
if (EndLoc)
*EndLoc = Tok.getLocation();
>From 9837c108587d22cf68c989da154d091231dd978d Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Thu, 20 Aug 2026 17:53:12 +0000
Subject: [PATCH 4/8] Apply clang-format
---
.../clangd/unittests/HoverTests.cpp | 7 +++--
clang/lib/Parse/ParseHLSL.cpp | 27 +++++++++----------
clang/lib/Sema/SemaHLSL.cpp | 4 +--
3 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 2676e4c7db280..1a0b878be8637 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5554,7 +5554,7 @@ TEST(Hover, HLSLSemanticAnnotations) {
)hlsl",
"TEXCOORD", "[TEXCOORD]"},
};
-
+
for (const auto &Case : Cases) {
SCOPED_TRACE(Case.Code);
Annotations T(Case.Code);
@@ -5566,11 +5566,10 @@ TEST(Hover, HLSLSemanticAnnotations) {
<< Case.ExpectedName;
EXPECT_EQ(H->Name, Case.ExpectedName);
EXPECT_EQ(H->Definition, Case.ExpectedDefinition);
-
+
if (llvm::StringRef(Case.ExpectedDefinition).contains("TEXCOORD")) {
EXPECT_EQ(H->Definition.find("\""), std::string::npos)
- << "Definition leaked internal semantic arguments: "
- << H->Definition;
+ << "Definition leaked internal semantic arguments: " << H->Definition;
}
}
}
diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp
index cc1f3239d814d..45a52a5115807 100644
--- a/clang/lib/Parse/ParseHLSL.cpp
+++ b/clang/lib/Parse/ParseHLSL.cpp
@@ -188,7 +188,7 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
AttrKind =
ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_HLSLAnnotation);
-SourceLocation Loc = ConsumeToken();
+ SourceLocation Loc = ConsumeToken();
if (EndLoc)
*EndLoc = Tok.getLocation();
@@ -340,16 +340,15 @@ SourceLocation Loc = ConsumeToken();
break;
}
case ParsedAttr::AT_HLSLParsedSemantic: {
- ASTContext &Ctx = Actions.getASTContext();
- ArgExprs.push_back(IntegerLiteral::Create(
- Ctx, llvm::APInt(Ctx.getTypeSize(Ctx.IntTy), Semantic.Index),
- Ctx.IntTy, SourceLocation()));
- ArgExprs.push_back(IntegerLiteral::Create(
- Ctx, llvm::APInt(1, Semantic.Explicit), Ctx.BoolTy,
- SourceLocation()));
- II = PP.getIdentifierInfo(Semantic.Name);
- break;
-}
+ ASTContext &Ctx = Actions.getASTContext();
+ ArgExprs.push_back(IntegerLiteral::Create(
+ Ctx, llvm::APInt(Ctx.getTypeSize(Ctx.IntTy), Semantic.Index), Ctx.IntTy,
+ SourceLocation()));
+ ArgExprs.push_back(IntegerLiteral::Create(
+ Ctx, llvm::APInt(1, Semantic.Explicit), Ctx.BoolTy, SourceLocation()));
+ II = PP.getIdentifierInfo(Semantic.Name);
+ break;
+ }
case ParsedAttr::UnknownAttribute: // FIXME: maybe this is obsolete?
break;
default:
@@ -358,8 +357,8 @@ SourceLocation Loc = ConsumeToken();
}
ParsedAttr::Form Form = (AttrKind == ParsedAttr::AT_HLSLParsedSemantic)
- ? ParsedAttr::Form::Microsoft()
- : ParsedAttr::Form::HLSLAnnotation();
+ ? ParsedAttr::Form::Microsoft()
+ : ParsedAttr::Form::HLSLAnnotation();
Attrs.addNew(II, SourceRange(Loc, AttrEndLoc), AttributeScopeInfo(),
- ArgExprs.data(), ArgExprs.size(), Form);
+ ArgExprs.data(), ArgExprs.size(), Form);
}
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 81b91b78ee321..a482877ec679a 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2021,8 +2021,8 @@ void SemaHLSL::handleSemanticAttr(Decl *D, const ParsedAttr &AL) {
if (AL.getKind() == ParsedAttr::AT_HLSLParsedSemantic) {
diagnoseSystemSemanticAttr(D, AL, Index);
} else {
- D->addAttr(HLSLUnparsedSemanticAttr::Create(
- SemaRef.getASTContext(), IndexValue, ExplicitIndex, AL));
+ D->addAttr(HLSLUnparsedSemanticAttr::Create(SemaRef.getASTContext(),
+ IndexValue, ExplicitIndex, AL));
}
}
>From a94877766cce010fd0c1b76f278db0ae0097583f Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Fri, 28 Aug 2026 09:57:58 +0000
Subject: [PATCH 5/8] Fix getAnySemanticAttr
---
.../clangd/unittests/HoverTests.cpp | 16 ++++++++
clang/include/clang/Sema/SemaHLSL.h | 2 +-
clang/lib/Sema/SemaHLSL.cpp | 40 ++++++++++++++-----
3 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 1a0b878be8637..9d141dd6834f5 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5574,6 +5574,22 @@ TEST(Hover, HLSLSemanticAnnotations) {
}
}
+TEST(Hover, HLSLUnparsedSemanticName) {
+ Annotations T(R"hlsl(
+ typedef float float4 __attribute__((ext_vector_type(4)));
+ float4 main(float4 pos : ^COLOR) : SV_Target {
+ return pos;
+ }
+ )hlsl");
+ TestTU TU = TestTU::withCode(T.code());
+ configureHLSL(TU);
+ auto AST = TU.build();
+ auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
+ ASSERT_TRUE(H) << "Hover should have been returned for COLOR semantic!";
+ llvm::errs() << "HI.Name = " << H->Name << "\n";
+ llvm::errs() << "HI.Definition = " << H->Definition << "\n";
+}
+
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index 8928524e49783..fb1fa5ab97631 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -285,7 +285,7 @@ class SemaHLSL : public SemaBase {
// Information about the current subtree being flattened.
struct SemanticInfo {
- HLSLParsedSemanticAttr *Semantic;
+ Attr *Semantic;
std::optional<uint32_t> Index = std::nullopt;
};
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index a482877ec679a..9109700581fb5 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -862,6 +862,23 @@ void SemaHLSL::ActOnTopLevelFunction(FunctionDecl *FD) {
}
}
+static Attr *getAnySemanticAttr(const Decl *D) {
+ if (Attr *A = D->getAttr<HLSLParsedSemanticAttr>())
+ return A;
+ if (Attr *A = D->getAttr<HLSLUnparsedSemanticAttr>())
+ return A;
+ return nullptr;
+}
+
+static std::optional<uint32_t> getSemanticIndexOf(const Attr *A) {
+ if (const auto *PA = dyn_cast<HLSLParsedSemanticAttr>(A))
+ return PA->getSemanticIndex();
+ if (const auto *UA = dyn_cast<HLSLUnparsedSemanticAttr>(A))
+ return UA->getExplicitIndex() ? std::optional<uint32_t>(UA->getIndex())
+ : std::nullopt;
+ return std::nullopt;
+}
+
static bool isVkPipelineBuiltin(const ASTContext &AstContext, FunctionDecl *FD,
HLSLAppliedSemanticAttr *Semantic,
bool IsInput) {
@@ -892,9 +909,9 @@ bool SemaHLSL::determineActiveSemanticOnScalar(FunctionDecl *FD,
SemanticInfo &ActiveSemantic,
SemaHLSL::SemanticContext &SC) {
if (ActiveSemantic.Semantic == nullptr) {
- ActiveSemantic.Semantic = D->getAttr<HLSLParsedSemanticAttr>();
+ ActiveSemantic.Semantic = getAnySemanticAttr(D);
if (ActiveSemantic.Semantic)
- ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
+ ActiveSemantic.Index = getSemanticIndexOf(ActiveSemantic.Semantic);
}
if (!ActiveSemantic.Semantic) {
@@ -954,9 +971,9 @@ bool SemaHLSL::determineActiveSemantic(FunctionDecl *FD,
SemanticInfo &ActiveSemantic,
SemaHLSL::SemanticContext &SC) {
if (ActiveSemantic.Semantic == nullptr) {
- ActiveSemantic.Semantic = D->getAttr<HLSLParsedSemanticAttr>();
+ ActiveSemantic.Semantic = getAnySemanticAttr(D);
if (ActiveSemantic.Semantic)
- ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
+ ActiveSemantic.Index = getSemanticIndexOf(ActiveSemantic.Semantic);
}
const Type *T = D == FD ? &*FD->getReturnType() : &*D->getType();
@@ -1050,9 +1067,9 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
for (ParmVarDecl *Param : FD->parameters()) {
SemanticInfo ActiveSemantic;
- ActiveSemantic.Semantic = Param->getAttr<HLSLParsedSemanticAttr>();
+ ActiveSemantic.Semantic = getAnySemanticAttr(Param);
if (ActiveSemantic.Semantic)
- ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
+ ActiveSemantic.Index = getSemanticIndexOf(ActiveSemantic.Semantic);
// FIXME: Verify output semantics in parameters.
if (!determineActiveSemantic(FD, Param, Param, ActiveSemantic, InputSC)) {
@@ -1064,9 +1081,9 @@ void SemaHLSL::CheckEntryPoint(FunctionDecl *FD) {
SemanticInfo ActiveSemantic;
SemaHLSL::SemanticContext OutputSC = {};
OutputSC.CurrentIOType = IOType::Out;
- ActiveSemantic.Semantic = FD->getAttr<HLSLParsedSemanticAttr>();
+ ActiveSemantic.Semantic = getAnySemanticAttr(FD);
if (ActiveSemantic.Semantic)
- ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex();
+ ActiveSemantic.Index = getSemanticIndexOf(ActiveSemantic.Semantic);
if (!FD->getReturnType()->isVoidType())
determineActiveSemantic(FD, FD, FD, ActiveSemantic, OutputSC);
}
@@ -2018,11 +2035,12 @@ void SemaHLSL::handleSemanticAttr(Decl *D, const ParsedAttr &AL) {
assert(IndexValue > 0 ? ExplicitIndex : true);
std::optional<unsigned> Index =
ExplicitIndex ? std::optional<unsigned>(IndexValue) : std::nullopt;
- if (AL.getKind() == ParsedAttr::AT_HLSLParsedSemantic) {
+ if (AL.getKind() == ParsedAttr::AT_HLSLParsedSemantic ||
+ AL.getAttrName()->getName().starts_with_insensitive("SV_")) {
diagnoseSystemSemanticAttr(D, AL, Index);
} else {
- D->addAttr(HLSLUnparsedSemanticAttr::Create(SemaRef.getASTContext(),
- IndexValue, ExplicitIndex, AL));
+ D->addAttr(HLSLUnparsedSemanticAttr::Create(
+ SemaRef.getASTContext(), IndexValue, ExplicitIndex, AL));
}
}
>From 32761dd1acc7ab808c2b6cad82302c268928d28e Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Sat, 29 Aug 2026 17:07:35 +0000
Subject: [PATCH 6/8] Remove debug prints, add proper assertions in
HLSLUnparsedSemanticName test
---
clang-tools-extra/clangd/unittests/HoverTests.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 9d141dd6834f5..11628d0d46e3f 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -5586,8 +5586,8 @@ TEST(Hover, HLSLUnparsedSemanticName) {
auto AST = TU.build();
auto H = getHover(AST, T.point(), format::getLLVMStyle(), nullptr);
ASSERT_TRUE(H) << "Hover should have been returned for COLOR semantic!";
- llvm::errs() << "HI.Name = " << H->Name << "\n";
- llvm::errs() << "HI.Definition = " << H->Definition << "\n";
+ EXPECT_EQ(H->Name, "COLOR");
+ EXPECT_EQ(H->Definition, "[COLOR]");
}
} // namespace
>From d86773f384948273272c661bcac3549beb0f8af7 Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Sat, 29 Aug 2026 17:12:56 +0000
Subject: [PATCH 7/8] Apply clang-format to SemaHLSL.cpp
---
clang/lib/Sema/SemaHLSL.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 9109700581fb5..275695f4b52f0 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -875,7 +875,7 @@ static std::optional<uint32_t> getSemanticIndexOf(const Attr *A) {
return PA->getSemanticIndex();
if (const auto *UA = dyn_cast<HLSLUnparsedSemanticAttr>(A))
return UA->getExplicitIndex() ? std::optional<uint32_t>(UA->getIndex())
- : std::nullopt;
+ : std::nullopt;
return std::nullopt;
}
@@ -2036,11 +2036,11 @@ void SemaHLSL::handleSemanticAttr(Decl *D, const ParsedAttr &AL) {
std::optional<unsigned> Index =
ExplicitIndex ? std::optional<unsigned>(IndexValue) : std::nullopt;
if (AL.getKind() == ParsedAttr::AT_HLSLParsedSemantic ||
- AL.getAttrName()->getName().starts_with_insensitive("SV_")) {
+ AL.getAttrName()->getName().starts_with_insensitive("SV_")) {
diagnoseSystemSemanticAttr(D, AL, Index);
} else {
- D->addAttr(HLSLUnparsedSemanticAttr::Create(
- SemaRef.getASTContext(), IndexValue, ExplicitIndex, AL));
+ D->addAttr(HLSLUnparsedSemanticAttr::Create(SemaRef.getASTContext(),
+ IndexValue, ExplicitIndex, AL));
}
}
>From 30061a52eba1f1217cbedecfa8295dacecb86f76 Mon Sep 17 00:00:00 2001
From: Maria Fernanda Guimaraes <mariafefe201 at gmail.com>
Date: Sun, 30 Aug 2026 11:16:02 +0000
Subject: [PATCH 8/8] Trigger CI re-run
More information about the cfe-commits
mailing list