From 9abd7ddf395cb612ff2bca833a70394ffb241885 Mon Sep 17 00:00:00 2001 From: Ashley Coleman 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 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 BufferErr3; void main() { (void)Buff.__handle; // expected-error {{'__handle' is a private member of 'hlsl::Buffer>'}} // expected-note@* {{implicitly declared private here}} + + // expected-error@+2 {{cannot assign to return value because function 'operator[]' returns a const value}} + // expected-note@*:* {{(frontend): function 'operator[]' which returns const-qualified type 'vector' declared here}} + Buff[0] = 0.0; } From 4494d423a2e71c53dcbb49818e96bc09d77db7fa Mon Sep 17 00:00:00 2001 From: Ashley Coleman 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@+2 {{cannot assign to return value because function 'operator[]' returns a const value}} - // expected-note@*:* {{(frontend): function 'operator[]' which returns const-qualified type 'vector' declared here}} + // expected-note@* {{function 'operator[]' which returns const-qualified type 'vector' 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 BufferErr4; void main() { (void)Buff.__handle; // expected-error {{'__handle' is a private member of 'hlsl::StructuredBuffer>'}} // expected-note@* {{implicitly declared private here}} + + // expected-error@+2 {{cannot assign to return value because function 'operator[]' returns a const value}} + // expected-note@* {{function 'operator[]' which returns const-qualified type 'vector' declared here}} + Buff[0] = 0.0; } From eeb4d59ec00a823d0ccad3011aff50d50b2360c3 Mon Sep 17 00:00:00 2001 From: Ashley Coleman 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 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 Fields; - bool IsConstResourceClass = false; + ResourceClass RClass; public: friend struct TemplateParameterListBuilder; From 86e125a2183d9a1b524fcb228884e10592797791 Mon Sep 17 00:00:00 2001 From: Ashley Coleman 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 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 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 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 {{.*}} -// CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} '' 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]]' 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 {{.*}} +// CHECK-SUBSCRIPT-UAV-NEXT: DeclRefExpr {{.*}} '' 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]]' 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 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 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 {{.*}} -// CHECK-NEXT: DeclRefExpr {{.*}} '' 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 {{.*}} +// CHECK-UAV-NEXT: DeclRefExpr {{.*}} '' 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]]' 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]]' 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 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 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(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 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 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(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