Skip to content

Commit 61f7f9b

Browse files
authored
[Clang][docs] Modify generator for HLSL semantics documentation (#157841)
HLSL semantics are split between system semantics with some kind of spelling, and user semantics with no actual spelling. Those have been documented as normal function attributes, but they'd benefit from a custom section with a slightly different handling. This will allow #152537 to land. Verified the resulting RST file, and only diff are around HLSL semantics. Rendered output: <img width="1064" height="1035" alt="Screenshot from 2025-09-10 14-05-08" src="https://github.com/user-attachments/assets/554b70d6-2bf8-4131-b343-8f379babaca8" />
1 parent 2f755c5 commit 61f7f9b

File tree

2 files changed

+68
-31
lines changed

2 files changed

+68
-31
lines changed

clang/include/clang/Basic/AttrDocs.td

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8367,6 +8367,23 @@ flag.
83678367
}];
83688368
}
83698369

8370+
def DocHLSLSemantics : DocumentationCategory<"HLSL Semantics"> {
8371+
let Content = [{
8372+
A semantic is a string attached to a shader input or output that conveys
8373+
information about the intended use of a parameter. Semantics are required on
8374+
all variables passed between shader stages. The syntax for adding a semantic
8375+
to a shader variable is shown here (Variable Syntax (DirectX HLSL)).
8376+
8377+
In general, data passed between pipeline stages is completely generic and is
8378+
not uniquely interpreted by the system; arbitrary semantics are allowed which
8379+
have no special meaning. Parameters (in Direct3D 10 and later) which contain
8380+
these special semantics are referred to as System-Value Semantics.
8381+
8382+
More information is available here:
8383+
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics
8384+
}];
8385+
}
8386+
83708387
def WaveSizeDocs : Documentation {
83718388
let Category = DocCatFunction;
83728389
let Content = [{
@@ -8604,7 +8621,7 @@ randomized.
86048621
}
86058622

86068623
def HLSLSV_GroupThreadIDDocs : Documentation {
8607-
let Category = DocCatFunction;
8624+
let Category = DocHLSLSemantics;
86088625
let Content = [{
86098626
The ``SV_GroupThreadID`` semantic, when applied to an input parameter, specifies which
86108627
individual thread within a thread group is executing in. This attribute is
@@ -8615,7 +8632,7 @@ The full documentation is available here: https://docs.microsoft.com/en-us/windo
86158632
}
86168633

86178634
def HLSLSV_GroupIDDocs : Documentation {
8618-
let Category = DocCatFunction;
8635+
let Category = DocHLSLSemantics;
86198636
let Content = [{
86208637
The ``SV_GroupID`` semantic, when applied to an input parameter, specifies which
86218638
thread group a shader is executing in. This attribute is only supported in compute shaders.
@@ -8625,7 +8642,7 @@ The full documentation is available here: https://docs.microsoft.com/en-us/windo
86258642
}
86268643

86278644
def HLSLSV_GroupIndexDocs : Documentation {
8628-
let Category = DocCatFunction;
8645+
let Category = DocHLSLSemantics;
86298646
let Content = [{
86308647
The ``SV_GroupIndex`` semantic, when applied to an input parameter, specifies a
86318648
data binding to map the group index to the specified parameter. This attribute
@@ -8682,7 +8699,7 @@ The full documentation is available here: https://learn.microsoft.com/en-us/wind
86828699
}
86838700

86848701
def HLSLSV_DispatchThreadIDDocs : Documentation {
8685-
let Category = DocCatFunction;
8702+
let Category = DocHLSLSemantics;
86868703
let Content = [{
86878704
The ``SV_DispatchThreadID`` semantic, when applied to an input parameter,
86888705
specifies a data binding to map the global thread offset within the Dispatch
@@ -8697,7 +8714,7 @@ The full documentation is available here: https://docs.microsoft.com/en-us/windo
86978714
}
86988715

86998716
def HLSLSV_PositionDocs : Documentation {
8700-
let Category = DocCatFunction;
8717+
let Category = DocHLSLSemantics;
87018718
let Content = [{
87028719
The ``SV_Position`` semantic, when applied to an input parameter in a pixel
87038720
shader, contains the location of the pixel center (x, y) in screen space.

clang/utils/TableGen/ClangAttrEmitter.cpp

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5209,6 +5209,14 @@ class SpellingList {
52095209
Other.Spellings[Kind].end());
52105210
}
52115211
}
5212+
5213+
bool hasSpelling() const {
5214+
for (size_t Kind = 0; Kind < NumSpellingKinds; ++Kind) {
5215+
if (Spellings[Kind].size() > 0)
5216+
return true;
5217+
}
5218+
return false;
5219+
}
52125220
};
52135221

52145222
class DocumentationData {
@@ -5246,6 +5254,16 @@ GetAttributeHeadingAndSpellings(const Record &Documentation,
52465254
// documentation. This may not be a limiting factor since the spellings
52475255
// should generally be consistently applied across the category.
52485256

5257+
if (Cat == "HLSL Semantics") {
5258+
if (!Attribute.getName().starts_with("HLSL"))
5259+
PrintFatalError(Attribute.getLoc(),
5260+
"HLSL semantic attribute name must start with HLSL");
5261+
5262+
assert(Attribute.getName().size() > 4);
5263+
std::string Name = Attribute.getName().substr(4).str();
5264+
return std::make_pair(std::move(Name), SpellingList());
5265+
}
5266+
52495267
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute);
52505268
if (Spellings.empty())
52515269
PrintFatalError(Attribute.getLoc(),
@@ -5296,37 +5314,39 @@ static void WriteDocumentation(const RecordKeeper &Records,
52965314
OS << ".. _" << Label << ":\n\n";
52975315
OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n";
52985316

5299-
// List what spelling syntaxes the attribute supports.
5300-
// Note: "#pragma clang attribute" is handled outside the spelling kinds loop
5301-
// so it must be last.
5302-
OS << ".. csv-table:: Supported Syntaxes\n";
5303-
OS << " :header: \"GNU\", \"C++11\", \"C23\", \"``__declspec``\",";
5304-
OS << " \"Keyword\", \"``#pragma``\", \"HLSL Annotation\", \"``#pragma "
5305-
"clang ";
5306-
OS << "attribute``\"\n\n \"";
5307-
for (size_t Kind = 0; Kind != NumSpellingKinds; ++Kind) {
5308-
SpellingKind K = (SpellingKind)Kind;
5309-
// TODO: List Microsoft (IDL-style attribute) spellings once we fully
5310-
// support them.
5311-
if (K == SpellingKind::Microsoft)
5312-
continue;
5317+
if (Doc.SupportedSpellings.hasSpelling()) {
5318+
// List what spelling syntaxes the attribute supports.
5319+
// Note: "#pragma clang attribute" is handled outside the spelling kinds
5320+
// loop so it must be last.
5321+
OS << ".. csv-table:: Supported Syntaxes\n";
5322+
OS << " :header: \"GNU\", \"C++11\", \"C23\", \"``__declspec``\",";
5323+
OS << " \"Keyword\", \"``#pragma``\", \"HLSL Annotation\", \"``#pragma "
5324+
"clang ";
5325+
OS << "attribute``\"\n\n \"";
5326+
for (size_t Kind = 0; Kind != NumSpellingKinds; ++Kind) {
5327+
SpellingKind K = (SpellingKind)Kind;
5328+
// TODO: List Microsoft (IDL-style attribute) spellings once we fully
5329+
// support them.
5330+
if (K == SpellingKind::Microsoft)
5331+
continue;
53135332

5314-
bool PrintedAny = false;
5315-
for (StringRef Spelling : Doc.SupportedSpellings[K]) {
5316-
if (PrintedAny)
5317-
OS << " |br| ";
5318-
OS << "``" << Spelling << "``";
5319-
PrintedAny = true;
5333+
bool PrintedAny = false;
5334+
for (StringRef Spelling : Doc.SupportedSpellings[K]) {
5335+
if (PrintedAny)
5336+
OS << " |br| ";
5337+
OS << "``" << Spelling << "``";
5338+
PrintedAny = true;
5339+
}
5340+
5341+
OS << "\",\"";
53205342
}
53215343

5322-
OS << "\",\"";
5344+
if (getPragmaAttributeSupport(Records).isAttributedSupported(
5345+
*Doc.Attribute))
5346+
OS << "Yes";
5347+
OS << "\"\n\n";
53235348
}
53245349

5325-
if (getPragmaAttributeSupport(Records).isAttributedSupported(
5326-
*Doc.Attribute))
5327-
OS << "Yes";
5328-
OS << "\"\n\n";
5329-
53305350
// If the attribute is deprecated, print a message about it, and possibly
53315351
// provide a replacement attribute.
53325352
if (!Doc.Documentation->isValueUnset("Deprecated")) {

0 commit comments

Comments
 (0)