[clang] [HLSL] Disallow writing to readonly resources (PR #147806)
Ashley Coleman via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 11 12:31:28 PDT 2025
https://github.com/V-FEXrt updated https://github.com/llvm/llvm-project/pull/147806
>From 9abd7ddf395cb612ff2bca833a70394ffb241885 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Wed, 9 Jul 2025 12:48:51 -0600
Subject: [PATCH 1/6] [HLSL] Disallow writing to readonly resources
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 15 ++++++++++++++-
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 1 +
clang/test/SemaHLSL/BuiltIns/Buffers.hlsl | 4 ++++
3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index e5c6220bfb47d..7c08a917f24be 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -613,6 +613,17 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
assert(!Record->isCompleteDefinition() && "record is already complete");
+ switch (RC) {
+ case llvm::dxil::ResourceClass::UAV:
+ IsConstResourceClass = false;
+ break;
+ case llvm::dxil::ResourceClass::SRV:
+ case llvm::dxil::ResourceClass::CBuffer:
+ case llvm::dxil::ResourceClass::Sampler:
+ IsConstResourceClass = true;
+ break;
+ };
+
ASTContext &Ctx = SemaRef.getASTContext();
TypeSourceInfo *ElementTypeInfo =
Ctx.getTrivialTypeSourceInfo(getHandleElementType(), SourceLocation());
@@ -697,7 +708,9 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators() {
AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
addHandleAccessFunction(Subscript, /*IsConst=*/true, /*IsRef=*/true);
- addHandleAccessFunction(Subscript, /*IsConst=*/false, /*IsRef=*/true);
+ if (!IsConstResourceClass)
+ addHandleAccessFunction(Subscript, /*IsConst=*/false, /*IsRef=*/true);
+
return *this;
}
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index a52e2938104c7..d8fac3cebc94a 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -52,6 +52,7 @@ class BuiltinTypeDeclBuilder {
ClassTemplateDecl *PrevTemplate = nullptr;
NamespaceDecl *HLSLNamespace = nullptr;
llvm::StringMap<FieldDecl *> Fields;
+ bool IsConstResourceClass = false;
public:
friend struct TemplateParameterListBuilder;
diff --git a/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl b/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl
index 477a16a454a9c..7c4a6d7abc538 100644
--- a/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl
@@ -111,4 +111,8 @@ Buffer<threeDoubles> BufferErr3;
void main() {
(void)Buff.__handle; // expected-error {{'__handle' is a private member of 'hlsl::Buffer<vector<float, 3>>'}}
// expected-note@* {{implicitly declared private here}}
+
+ // expected-error at +2 {{cannot assign to return value because function 'operator[]' returns a const value}}
+ // expected-note@*:* {{(frontend): function 'operator[]' which returns const-qualified type 'vector<float const hlsl_device &, 3>' declared here}}
+ Buff[0] = 0.0;
}
>From 4494d423a2e71c53dcbb49818e96bc09d77db7fa Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Wed, 9 Jul 2025 13:15:51 -0600
Subject: [PATCH 2/6] Finish tests
---
clang/test/SemaHLSL/BuiltIns/Buffers.hlsl | 2 +-
clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl b/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl
index 7c4a6d7abc538..d7c6876d3b9e3 100644
--- a/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl
@@ -113,6 +113,6 @@ void main() {
// expected-note@* {{implicitly declared private here}}
// expected-error at +2 {{cannot assign to return value because function 'operator[]' returns a const value}}
- // expected-note@*:* {{(frontend): function 'operator[]' which returns const-qualified type 'vector<float const hlsl_device &, 3>' declared here}}
+ // expected-note@* {{function 'operator[]' which returns const-qualified type 'vector<float const hlsl_device &, 3>' declared here}}
Buff[0] = 0.0;
}
diff --git a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl
index bf541f4a07da7..fbd9288590adc 100644
--- a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl
@@ -28,4 +28,8 @@ StructuredBuffer<Empty> BufferErr4;
void main() {
(void)Buff.__handle; // expected-error {{'__handle' is a private member of 'hlsl::StructuredBuffer<vector<float, 3>>'}}
// expected-note@* {{implicitly declared private here}}
+
+ // expected-error at +2 {{cannot assign to return value because function 'operator[]' returns a const value}}
+ // expected-note@* {{function 'operator[]' which returns const-qualified type 'vector<float const hlsl_device &, 3>' declared here}}
+ Buff[0] = 0.0;
}
>From eeb4d59ec00a823d0ccad3011aff50d50b2360c3 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Wed, 9 Jul 2025 14:55:55 -0600
Subject: [PATCH 3/6] Address comments
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 15 +++------------
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 2 +-
2 files changed, 4 insertions(+), 13 deletions(-)
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 7c08a917f24be..cf096bac4001c 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -613,16 +613,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
assert(!Record->isCompleteDefinition() && "record is already complete");
- switch (RC) {
- case llvm::dxil::ResourceClass::UAV:
- IsConstResourceClass = false;
- break;
- case llvm::dxil::ResourceClass::SRV:
- case llvm::dxil::ResourceClass::CBuffer:
- case llvm::dxil::ResourceClass::Sampler:
- IsConstResourceClass = true;
- break;
- };
+ RClass = RC;
ASTContext &Ctx = SemaRef.getASTContext();
TypeSourceInfo *ElementTypeInfo =
@@ -631,7 +622,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
// add handle member with resource type attributes
QualType AttributedResTy = QualType();
SmallVector<const Attr *> Attrs = {
- HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
+ HLSLResourceClassAttr::CreateImplicit(Ctx, RClass),
IsROV ? HLSLROVAttr::CreateImplicit(Ctx) : nullptr,
RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) : nullptr,
ElementTypeInfo
@@ -708,7 +699,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators() {
AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
addHandleAccessFunction(Subscript, /*IsConst=*/true, /*IsRef=*/true);
- if (!IsConstResourceClass)
+ if (RClass == llvm::dxil::ResourceClass::UAV)
addHandleAccessFunction(Subscript, /*IsConst=*/false, /*IsRef=*/true);
return *this;
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index d8fac3cebc94a..426c0550e1c6c 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -52,7 +52,7 @@ class BuiltinTypeDeclBuilder {
ClassTemplateDecl *PrevTemplate = nullptr;
NamespaceDecl *HLSLNamespace = nullptr;
llvm::StringMap<FieldDecl *> Fields;
- bool IsConstResourceClass = false;
+ ResourceClass RClass;
public:
friend struct TemplateParameterListBuilder;
>From 86e125a2183d9a1b524fcb228884e10592797791 Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Thu, 10 Jul 2025 13:32:24 -0600
Subject: [PATCH 4/6] Fix tests
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 6 ++--
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 2 +-
.../test/AST/HLSL/StructuredBuffers-AST.hlsl | 36 +++++++++----------
clang/test/AST/HLSL/TypedBuffers-AST.hlsl | 31 ++++++++--------
4 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index cf096bac4001c..257fdfd64ecf2 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -613,7 +613,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
assert(!Record->isCompleteDefinition() && "record is already complete");
- RClass = RC;
+ ResClass = RC;
ASTContext &Ctx = SemaRef.getASTContext();
TypeSourceInfo *ElementTypeInfo =
@@ -622,7 +622,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
// add handle member with resource type attributes
QualType AttributedResTy = QualType();
SmallVector<const Attr *> Attrs = {
- HLSLResourceClassAttr::CreateImplicit(Ctx, RClass),
+ HLSLResourceClassAttr::CreateImplicit(Ctx, ResClass),
IsROV ? HLSLROVAttr::CreateImplicit(Ctx) : nullptr,
RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) : nullptr,
ElementTypeInfo
@@ -699,7 +699,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators() {
AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
addHandleAccessFunction(Subscript, /*IsConst=*/true, /*IsRef=*/true);
- if (RClass == llvm::dxil::ResourceClass::UAV)
+ if (ResClass == llvm::dxil::ResourceClass::UAV)
addHandleAccessFunction(Subscript, /*IsConst=*/false, /*IsRef=*/true);
return *this;
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 426c0550e1c6c..91bf8748d0a45 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -52,7 +52,7 @@ class BuiltinTypeDeclBuilder {
ClassTemplateDecl *PrevTemplate = nullptr;
NamespaceDecl *HLSLNamespace = nullptr;
llvm::StringMap<FieldDecl *> Fields;
- ResourceClass RClass;
+ ResourceClass ResClass;
public:
friend struct TemplateParameterListBuilder;
diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
index b74e183eec9cc..1c8b9c10f5a98 100644
--- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
@@ -12,7 +12,7 @@
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
// RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \
-// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT,CHECK-COUNTER,CHECK-LOAD %s
+// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT,CHECK-SUBSCRIPT-UAV,CHECK-COUNTER,CHECK-LOAD %s
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
// RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \
@@ -36,7 +36,7 @@
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
// RUN: -DRESOURCE=RasterizerOrderedStructuredBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedStructuredBuffer \
-// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-ROV,CHECK-SUBSCRIPT,CHECK-LOAD %s
+// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-ROV,CHECK-SUBSCRIPT,CHECK-SUBSCRIPT-UAV,CHECK-LOAD %s
// This test tests two different AST generations for each structured buffer.
// The "EMPTY" test mode verifies the AST generated by forward declaration
@@ -170,22 +170,22 @@ RESOURCE<float> Buffer;
// CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-SUBSCRIPT-NEXT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)'
-// CHECK-SUBSCRIPT-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
-// CHECK-SUBSCRIPT-NEXT: CompoundStmt
-// CHECK-SUBSCRIPT-NEXT: ReturnStmt
-// CHECK-SUBSCRIPT-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow
-// CHECK-SUBSCRIPT-NEXT: CallExpr {{.*}} 'hlsl_device element_type *'
-// CHECK-SUBSCRIPT-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
-// CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
-// CHECK-SUBSCRIPT-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
-// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::resource_class(
-// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::raw_buffer]]
-// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
-// CHECK-SUBSCRIPT-SAME: ' lvalue .__handle {{.*}}
-// CHECK-SUBSCRIPT-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
-// CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
-// CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
+// CHECK-SUBSCRIPT-UAV-NEXT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)'
+// CHECK-SUBSCRIPT-UAV-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
+// CHECK-SUBSCRIPT-UAV-NEXT: CompoundStmt
+// CHECK-SUBSCRIPT-UAV-NEXT: ReturnStmt
+// CHECK-SUBSCRIPT-UAV-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow
+// CHECK-SUBSCRIPT-UAV-NEXT: CallExpr {{.*}} 'hlsl_device element_type *'
+// CHECK-SUBSCRIPT-UAV-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
+// CHECK-SUBSCRIPT-UAV-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// CHECK-SUBSCRIPT-UAV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-SUBSCRIPT-UAV-SAME{LITERAL}: [[hlsl::resource_class(
+// CHECK-SUBSCRIPT-UAV-SAME{LITERAL}: [[hlsl::raw_buffer]]
+// CHECK-SUBSCRIPT-UAV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-SUBSCRIPT-UAV-SAME: ' lvalue .__handle {{.*}}
+// CHECK-SUBSCRIPT-UAV-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-SUBSCRIPT-UAV-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
+// CHECK-SUBSCRIPT-UAV-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(unsigned int) const'
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)'
diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
index d098e5a323ca7..d6b88e276762e 100644
--- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
@@ -126,7 +126,7 @@ RESOURCE<float> Buffer;
// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *'
// CHECK-NEXT: AlwaysInlineAttr
-// Subsctript operators
+// Subscript operators
// CHECK: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(unsigned int) const'
// CHECK-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
@@ -145,22 +145,21 @@ RESOURCE<float> Buffer;
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
-// CHECK-NEXT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)'
-// CHECK-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
-// CHECK-NEXT: CompoundStmt
-// CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow
-// CHECK-NEXT: CallExpr {{.*}} 'hlsl_device element_type *'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
-// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
-// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
+// CHECK-UAV-NEXT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)'
+// CHECK-UAV-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
+// CHECK-UAV-NEXT: CompoundStmt
+// CHECK-UAV-NEXT: ReturnStmt
+// CHECK-UAV-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow
+// CHECK-UAV-NEXT: CallExpr {{.*}} 'hlsl_device element_type *'
+// CHECK-UAV-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
+// CHECK-UAV-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// CHECK-UAV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
-// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
-// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
-// CHECK-SAME: ' lvalue .__handle {{.*}}
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
-// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
-// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
+// CHECK-UAV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
+// CHECK-UAV-SAME: ' lvalue .__handle {{.*}}
+// CHECK-UAV-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-UAV-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
+// CHECK-UAV-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
// Load method
>From fa20c2ae5a165fada082b0a58789ff6d34521d7a Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Fri, 11 Jul 2025 13:25:11 -0600
Subject: [PATCH 5/6] Address comments
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 12 ++++++++----
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 2 +-
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 257fdfd64ecf2..f66d53f8acdcf 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -613,8 +613,6 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
ResourceClass RC, bool IsROV, bool RawBuffer, AccessSpecifier Access) {
assert(!Record->isCompleteDefinition() && "record is already complete");
- ResClass = RC;
-
ASTContext &Ctx = SemaRef.getASTContext();
TypeSourceInfo *ElementTypeInfo =
Ctx.getTrivialTypeSourceInfo(getHandleElementType(), SourceLocation());
@@ -622,7 +620,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
// add handle member with resource type attributes
QualType AttributedResTy = QualType();
SmallVector<const Attr *> Attrs = {
- HLSLResourceClassAttr::CreateImplicit(Ctx, ResClass),
+ HLSLResourceClassAttr::CreateImplicit(Ctx, RC),
IsROV ? HLSLROVAttr::CreateImplicit(Ctx) : nullptr,
RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Ctx) : nullptr,
ElementTypeInfo
@@ -699,7 +697,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators() {
AST.DeclarationNames.getCXXOperatorName(OO_Subscript);
addHandleAccessFunction(Subscript, /*IsConst=*/true, /*IsRef=*/true);
- if (ResClass == llvm::dxil::ResourceClass::UAV)
+ if (getResourceAttrs().ResourceClass == llvm::dxil::ResourceClass::UAV)
addHandleAccessFunction(Subscript, /*IsConst=*/false, /*IsRef=*/true);
return *this;
@@ -742,6 +740,12 @@ QualType BuiltinTypeDeclBuilder::getHandleElementType() {
return SemaRef.getASTContext().Char8Ty;
}
+HLSLAttributedResourceType::Attributes
+BuiltinTypeDeclBuilder::getResourceAttrs() {
+ QualType HandleType = getResourceHandleField()->getType();
+ return cast<HLSLAttributedResourceType>(HandleType)->getAttrs();
+}
+
// BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::startDefinition() {
// assert(!Record->isCompleteDefinition() && "record is already complete");
// Record->startDefinition();
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 91bf8748d0a45..5f30efb89febb 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -52,7 +52,6 @@ class BuiltinTypeDeclBuilder {
ClassTemplateDecl *PrevTemplate = nullptr;
NamespaceDecl *HLSLNamespace = nullptr;
llvm::StringMap<FieldDecl *> Fields;
- ResourceClass ResClass;
public:
friend struct TemplateParameterListBuilder;
@@ -96,6 +95,7 @@ class BuiltinTypeDeclBuilder {
QualType getFirstTemplateTypeParam();
QualType getHandleElementType();
Expr *getConstantIntExpr(int value);
+ HLSLAttributedResourceType::Attributes getResourceAttrs();
};
} // namespace hlsl
>From ff8f448b2d75bdccdd76a52531374b36511c825f Mon Sep 17 00:00:00 2001
From: Ashley Coleman <ascoleman at microsoft.com>
Date: Fri, 11 Jul 2025 13:31:04 -0600
Subject: [PATCH 6/6] Make functions const
---
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 4 ++--
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index f66d53f8acdcf..87f9ae07550c2 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -716,7 +716,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadMethods() {
return *this;
}
-FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() {
+FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() const {
auto I = Fields.find("__handle");
assert(I != Fields.end() &&
I->second->getType()->isHLSLAttributedResourceType() &&
@@ -741,7 +741,7 @@ QualType BuiltinTypeDeclBuilder::getHandleElementType() {
}
HLSLAttributedResourceType::Attributes
-BuiltinTypeDeclBuilder::getResourceAttrs() {
+BuiltinTypeDeclBuilder::getResourceAttrs() const {
QualType HandleType = getResourceHandleField()->getType();
return cast<HLSLAttributedResourceType>(HandleType)->getAttrs();
}
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 5f30efb89febb..36c4add20b225 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -91,11 +91,11 @@ class BuiltinTypeDeclBuilder {
BuiltinTypeDeclBuilder &addConsumeMethod();
private:
- FieldDecl *getResourceHandleField();
+ FieldDecl *getResourceHandleField() const;
QualType getFirstTemplateTypeParam();
QualType getHandleElementType();
Expr *getConstantIntExpr(int value);
- HLSLAttributedResourceType::Attributes getResourceAttrs();
+ HLSLAttributedResourceType::Attributes getResourceAttrs() const;
};
} // namespace hlsl
More information about the cfe-commits
mailing list