diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index ab3f9e4835802..ee212a9b50f36 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -8367,6 +8367,23 @@ flag. }]; } +def DocHLSLSemantics : DocumentationCategory<"HLSL Semantics"> { + let Content = [{ +A semantic is a string attached to a shader input or output that conveys +information about the intended use of a parameter. Semantics are required on +all variables passed between shader stages. The syntax for adding a semantic +to a shader variable is shown here (Variable Syntax (DirectX HLSL)). + +In general, data passed between pipeline stages is completely generic and is +not uniquely interpreted by the system; arbitrary semantics are allowed which +have no special meaning. Parameters (in Direct3D 10 and later) which contain +these special semantics are referred to as System-Value Semantics. + +More information is available here: +https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics + }]; +} + def WaveSizeDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -8604,7 +8621,7 @@ randomized. } def HLSLSV_GroupThreadIDDocs : Documentation { - let Category = DocCatFunction; + let Category = DocHLSLSemantics; let Content = [{ The ``SV_GroupThreadID`` semantic, when applied to an input parameter, specifies which 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 } def HLSLSV_GroupIDDocs : Documentation { - let Category = DocCatFunction; + let Category = DocHLSLSemantics; let Content = [{ The ``SV_GroupID`` semantic, when applied to an input parameter, specifies which 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 } def HLSLSV_GroupIndexDocs : Documentation { - let Category = DocCatFunction; + let Category = DocHLSLSemantics; let Content = [{ The ``SV_GroupIndex`` semantic, when applied to an input parameter, specifies a 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 } def HLSLSV_DispatchThreadIDDocs : Documentation { - let Category = DocCatFunction; + let Category = DocHLSLSemantics; let Content = [{ The ``SV_DispatchThreadID`` semantic, when applied to an input parameter, 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 } def HLSLSV_PositionDocs : Documentation { - let Category = DocCatFunction; + let Category = DocHLSLSemantics; let Content = [{ The ``SV_Position`` semantic, when applied to an input parameter in a pixel shader, contains the location of the pixel center (x, y) in screen space. diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index d63e79a5f5155..2e2f32a7a1cb1 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -5209,6 +5209,14 @@ class SpellingList { Other.Spellings[Kind].end()); } } + + bool hasSpelling() const { + for (size_t Kind = 0; Kind < NumSpellingKinds; ++Kind) { + if (Spellings[Kind].size() > 0) + return true; + } + return false; + } }; class DocumentationData { @@ -5246,6 +5254,16 @@ GetAttributeHeadingAndSpellings(const Record &Documentation, // documentation. This may not be a limiting factor since the spellings // should generally be consistently applied across the category. + if (Cat == "HLSL Semantics") { + if (!Attribute.getName().starts_with("HLSL")) + PrintFatalError(Attribute.getLoc(), + "HLSL semantic attribute name must start with HLSL"); + + assert(Attribute.getName().size() > 4); + std::string Name = Attribute.getName().substr(4).str(); + return std::make_pair(std::move(Name), SpellingList()); + } + std::vector Spellings = GetFlattenedSpellings(Attribute); if (Spellings.empty()) PrintFatalError(Attribute.getLoc(), @@ -5296,37 +5314,39 @@ static void WriteDocumentation(const RecordKeeper &Records, OS << ".. _" << Label << ":\n\n"; OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n"; - // List what spelling syntaxes the attribute supports. - // Note: "#pragma clang attribute" is handled outside the spelling kinds loop - // so it must be last. - OS << ".. csv-table:: Supported Syntaxes\n"; - OS << " :header: \"GNU\", \"C++11\", \"C23\", \"``__declspec``\","; - OS << " \"Keyword\", \"``#pragma``\", \"HLSL Annotation\", \"``#pragma " - "clang "; - OS << "attribute``\"\n\n \""; - for (size_t Kind = 0; Kind != NumSpellingKinds; ++Kind) { - SpellingKind K = (SpellingKind)Kind; - // TODO: List Microsoft (IDL-style attribute) spellings once we fully - // support them. - if (K == SpellingKind::Microsoft) - continue; + if (Doc.SupportedSpellings.hasSpelling()) { + // List what spelling syntaxes the attribute supports. + // Note: "#pragma clang attribute" is handled outside the spelling kinds + // loop so it must be last. + OS << ".. csv-table:: Supported Syntaxes\n"; + OS << " :header: \"GNU\", \"C++11\", \"C23\", \"``__declspec``\","; + OS << " \"Keyword\", \"``#pragma``\", \"HLSL Annotation\", \"``#pragma " + "clang "; + OS << "attribute``\"\n\n \""; + for (size_t Kind = 0; Kind != NumSpellingKinds; ++Kind) { + SpellingKind K = (SpellingKind)Kind; + // TODO: List Microsoft (IDL-style attribute) spellings once we fully + // support them. + if (K == SpellingKind::Microsoft) + continue; - bool PrintedAny = false; - for (StringRef Spelling : Doc.SupportedSpellings[K]) { - if (PrintedAny) - OS << " |br| "; - OS << "``" << Spelling << "``"; - PrintedAny = true; + bool PrintedAny = false; + for (StringRef Spelling : Doc.SupportedSpellings[K]) { + if (PrintedAny) + OS << " |br| "; + OS << "``" << Spelling << "``"; + PrintedAny = true; + } + + OS << "\",\""; } - OS << "\",\""; + if (getPragmaAttributeSupport(Records).isAttributedSupported( + *Doc.Attribute)) + OS << "Yes"; + OS << "\"\n\n"; } - if (getPragmaAttributeSupport(Records).isAttributedSupported( - *Doc.Attribute)) - OS << "Yes"; - OS << "\"\n\n"; - // If the attribute is deprecated, print a message about it, and possibly // provide a replacement attribute. if (!Doc.Documentation->isValueUnset("Deprecated")) {