[clang] [HLSL] Document all spellable attributes (PR #213346)
Justin Bogner via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 31 12:55:41 PDT 2026
https://github.com/bogner created https://github.com/llvm/llvm-project/pull/213346
This adds documentation for all of the hlsl-specific attributes that are user spellable.
The most interesting ones here are the control flow hints, `branch` and `flatten`, which are really user facing.
The rest of these are resource handle related attributes which are only usable on the internal `__hlsl_resource_t` type. These are only really interesting to an implementor of the HLSL library, but documentation for them seems valuable nonetheless.
Resolves llvm/llvm-project#211340
>From 45b9cbfa17ed5ef220ad3c6963992ef735b91eb4 Mon Sep 17 00:00:00 2001
From: Justin Bogner <mail at justinbogner.com>
Date: Fri, 31 Jul 2026 12:47:38 -0700
Subject: [PATCH] [HLSL] Document all spellable attributes
This adds documentation for all of the hlsl-specific attributes that are
user spellable.
The most interesting ones here are the control flow hints, `branch` and
`flatten`, which are really user facing.
The rest of these are resource handle related attributes which are only
usable on the internal `__hlsl_resource_t` type. These are only really
interesting to an implementor of the HLSL library, but documentation for
them seems valuable nonetheless.
Resolves llvm/llvm-project#211340
---
clang/include/clang/Basic/Attr.td | 50 +++++-----
clang/include/clang/Basic/AttrDocs.td | 92 +++++++++++++++++++
clang/lib/AST/TypePrinter.cpp | 2 +-
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 2 +-
clang/lib/Sema/SemaHLSL.cpp | 6 +-
clang/lib/Sema/SemaType.cpp | 2 +-
6 files changed, 123 insertions(+), 31 deletions(-)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 39c672322d515..76974768f9654 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4709,7 +4709,7 @@ def HLSLControlFlowHint: StmtAttr {
let Subjects = SubjectList<[IfStmt, SwitchStmt],
ErrorDiag, "'if' and 'switch' statements">;
let LangOpts = [HLSL];
- let Documentation = [InternalOnly];
+ let Documentation = [HLSLControlFlowHintDocs];
}
def CapturedRecord : InheritableAttr {
@@ -5200,24 +5200,6 @@ def HLSLShader : InheritableAttr {
}];
}
-def HLSLIsArray : TypeAttr {
- let Spellings = [CXX11<"hlsl", "is_array">];
- let LangOpts = [HLSL];
- let Documentation = [InternalOnly];
-}
-
-def HLSLIsMultiSampled : TypeAttr {
- let Spellings = [CXX11<"hlsl", "is_ms">];
- let LangOpts = [HLSL];
- let Documentation = [InternalOnly];
-}
-
-def HLSLROV : TypeAttr {
- let Spellings = [CXX11<"hlsl", "is_rov">];
- let LangOpts = [HLSL];
- let Documentation = [InternalOnly];
-}
-
def HLSLResourceClass : TypeAttr {
let Spellings = [CXX11<"hlsl", "resource_class">];
let LangOpts = [HLSL];
@@ -5226,7 +5208,7 @@ def HLSLResourceClass : TypeAttr {
/*is_string=*/true, ["SRV", "UAV", "CBuffer", "Sampler"],
["SRV", "UAV", "CBuffer", "Sampler"],
/*opt=*/0, /*fake=*/0, /*isExternalType=*/1>];
- let Documentation = [InternalOnly];
+ let Documentation = [HLSLResourceClassDocs];
}
def HLSLResourceDimension : TypeAttr {
@@ -5237,26 +5219,44 @@ def HLSLResourceDimension : TypeAttr {
/*is_string=*/true, ["Unknown", "1D", "2D", "3D", "Cube"],
["Unknown", "Dim1D", "Dim2D", "Dim3D", "Cube"],
/*opt=*/0, /*fake=*/0, /*isExternalType=*/1>];
- let Documentation = [InternalOnly];
+ let Documentation = [HLSLResourceDimensionDocs];
}
def HLSLContainedType : TypeAttr {
let Spellings = [CXX11<"hlsl", "contained_type">];
let LangOpts = [HLSL];
let Args = [TypeArgument<"Type", /*opt=*/0>];
- let Documentation = [InternalOnly];
+ let Documentation = [HLSLContainedTypeDocs];
}
def HLSLRawBuffer : TypeAttr {
let Spellings = [CXX11<"hlsl", "raw_buffer">];
let LangOpts = [HLSL];
- let Documentation = [InternalOnly];
+ let Documentation = [HLSLRawBufferDocs];
+}
+
+def HLSLIsArray : TypeAttr {
+ let Spellings = [CXX11<"hlsl", "is_array">];
+ let LangOpts = [HLSL];
+ let Documentation = [HLSLIsArrayDocs];
+}
+
+def HLSLIsMultiSampled : TypeAttr {
+ let Spellings = [CXX11<"hlsl", "is_ms">];
+ let LangOpts = [HLSL];
+ let Documentation = [HLSLIsMultiSampledDocs];
+}
+
+def HLSLIsROV : TypeAttr {
+ let Spellings = [CXX11<"hlsl", "is_rov">];
+ let LangOpts = [HLSL];
+ let Documentation = [HLSLIsROVDocs];
}
def HLSLIsCounter : TypeAttr {
let Spellings = [CXX11<"hlsl", "is_counter">];
let LangOpts = [HLSL];
- let Documentation = [InternalOnly];
+ let Documentation = [HLSLIsCounter];
}
def HLSLGroupSharedAddressSpace : TypeAttr {
@@ -5333,7 +5333,7 @@ def HLSLVkLocation : HLSLAnnotationAttr {
}
// `row_major` / `column_major` are HLSL keywords that select the in-memory
-// layout of a matrix-typed declaration.
+// layout of a matrix-typed declaration.
def HLSLRowMajor : TypeAttr {
let Spellings = [CustomKeyword<"row_major">];
let LangOpts = [HLSL];
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 05e4cb0870652..cd6a2e0fe63b2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -8995,6 +8995,23 @@ for details.
}];
}
+def HLLSControlFlowHintDocs : Documentation {
+ let Category = DocCatStmt;
+ let Heading = "branch, flatten";
+ let Content = [{
+The ``branch`` and ``flatten`` attributes can be applied to *if statements* in
+the HLSL language mode to control whether only one side of the statement is
+executed, or if both are executed and the result is chosen based on the
+condition.
+
+These control flow hints are preserved through the compilation and emitted in a
+backend-specific way.
+
+For details, see the Direct3D documentation for `if Statement
+<https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-if>`_
+ }]
+}
+
def AtomicDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
@@ -9088,6 +9105,81 @@ The full documentation is available here: https://learn.microsoft.com/en-us/wind
}];
}
+def HLSLResourceClassDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``hlsl::resource_class`` attribute specifies the resource class of the HLSL
+resource represented by a member variable of type ``__hlsl_resource_t``,
+declaring it to be an SRV, UAV, CBuffer, or Sampler resource. This attribute is
+only valid for resource handles.
+ }]
+}
+
+def HLSLResourceDimensionDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``hlsl::dimension`` attribute specifies the dimensions of the HLSL resource
+represented by a member veriable of type ``__hlsl_resource_t``, declaring the
+resource to have Unknown, 1D, 2D, 3D, or Cube dimension. This attribute is only
+valid for resource handles.
+ }]
+}
+
+def HLSLContainedTypeDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``hlsl::contained_type`` attribute specifies the type of the HLSL resource
+represented by a member veriable of type ``__hlsl_resource_t``. This attribute
+is only valid for resource handles.
+ }]
+}
+
+def HLSLRawBufferDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``hlsl::raw_buffer`` attribute specifies that the HLSL resource represented
+by a member veriable of type ``__hlsl_resource_t`` has raw buffer semantics.
+This attribute is only valid for resource handles.
+ }]
+}
+
+def HLSLIsArrayDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``hlsl::is_array`` attribute specifies that the HLSL resource represented
+by a member veriable of type ``__hlsl_resource_t`` has array dimensions. This
+attribute is only valid for resource handles.
+ }]
+}
+
+def HLSLIsMultiSampledDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``hlsl::is_array`` attribute specifies that the HLSL resource represented
+by a member veriable of type ``__hlsl_resource_t`` is multisampled. This
+attribute is only valid for resource handles.
+ }]
+}
+
+def HLSLIsROVDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``hlsl::is_rov`` attribute specifies that the HLSL resource represented by
+a member veriable of type ``__hlsl_resource_t`` is a rasterizer ordered view.
+This attribute is only valid for resource handles.
+ }]
+}
+
+def HLSLIsCounterDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``hlsl::is_counter`` attribute specifies that the HLSL resource represented
+by a member veriable of type ``__hlsl_resource_t`` is a counter buffer. This
+attribute is only valid for resource handles.
+ }]
+}
+
+
def HLSLGroupSharedAddressSpaceDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 60964d2859790..4b1346a62975f 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2025,7 +2025,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
llvm_unreachable("BTFTypeTag attribute handled separately");
case attr::HLSLResourceClass:
- case attr::HLSLROV:
+ case attr::HLSLIsROV:
case attr::HLSLRawBuffer:
case attr::HLSLContainedType:
case attr::HLSLIsCounter:
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 929e8bc824afa..5c17f0ebf6fdc 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1168,7 +1168,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addResourceMember(
QualType AttributedResTy = QualType();
SmallVector<const Attr *> Attrs = {
HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
- IsROV ? HLSLROVAttr::CreateImplicit(Ctx) : nullptr,
+ IsROV ? HLSLIsROVAttr::CreateImplicit(Ctx) : nullptr,
RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) : nullptr,
RD != ResourceDimension::Unknown
? HLSLResourceDimensionAttr::CreateImplicit(Ctx, RD)
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index c353c3fec3f62..760b3dcd718a2 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2140,7 +2140,7 @@ bool clang::CreateHLSLAttributedResourceType(
HasResourceDimension = true;
break;
}
- case attr::HLSLROV:
+ case attr::HLSLIsROV:
if (ResAttrs.IsROV) {
S.Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
return false;
@@ -2277,8 +2277,8 @@ bool SemaHLSL::handleResourceTypeAttr(QualType T, const ParsedAttr &AL) {
break;
}
- case ParsedAttr::AT_HLSLROV:
- A = HLSLROVAttr::Create(getASTContext(), ACI);
+ case ParsedAttr::AT_HLSLIsROV:
+ A = HLSLIsROVAttr::Create(getASTContext(), ACI);
break;
case ParsedAttr::AT_HLSLRawBuffer:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index dc3564c8b17fd..133e8234a247e 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9353,7 +9353,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
}
case ParsedAttr::AT_HLSLResourceClass:
case ParsedAttr::AT_HLSLResourceDimension:
- case ParsedAttr::AT_HLSLROV:
+ case ParsedAttr::AT_HLSLIsROV:
case ParsedAttr::AT_HLSLRawBuffer:
case ParsedAttr::AT_HLSLIsArray:
case ParsedAttr::AT_HLSLIsMultiSampled:
More information about the cfe-commits
mailing list