diff --git a/clang/include/clang/AST/HLSLResource.h b/clang/include/clang/AST/HLSLResource.h index 9cdd81b2d8dab..7440050c7b2b9 100644 --- a/clang/include/clang/AST/HLSLResource.h +++ b/clang/include/clang/AST/HLSLResource.h @@ -69,6 +69,11 @@ struct ResourceBindingAttrs { assert(hasImplicitOrderID()); return RegBinding->getImplicitBindingOrderID(); } + + void setImplicitOrderID(unsigned Value) const { + assert(hasBinding() && !isExplicit() && !hasImplicitOrderID()); + RegBinding->setImplicitBindingOrderID(Value); + } }; } // namespace hlsl diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 129b03c07c0bd..8dd234cb5d8ec 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -598,18 +598,17 @@ void SemaHLSL::ActOnFinishBuffer(Decl *Dcl, SourceLocation RBrace) { validatePackoffset(SemaRef, BufDecl); - // create buffer layout struct createHostLayoutStructForBuffer(SemaRef, BufDecl); - HLSLVkBindingAttr *VkBinding = Dcl->getAttr(); - HLSLResourceBindingAttr *RBA = Dcl->getAttr(); - if (!VkBinding && (!RBA || !RBA->hasRegisterSlot())) { + // Handle implicit binding if needed. + ResourceBindingAttrs ResourceAttrs(Dcl); + if (!ResourceAttrs.isExplicit()) { SemaRef.Diag(Dcl->getLocation(), diag::warn_hlsl_implicit_binding); // Use HLSLResourceBindingAttr to transfer implicit binding order_ID // to codegen. If it does not exist, create an implicit attribute. uint32_t OrderID = getNextImplicitBindingOrderID(); - if (RBA) - RBA->setImplicitBindingOrderID(OrderID); + if (ResourceAttrs.hasBinding()) + ResourceAttrs.setImplicitOrderID(OrderID); else addImplicitBindingAttrToDecl(SemaRef, BufDecl, BufDecl->isCBuffer() ? RegisterType::CBuffer @@ -1590,10 +1589,6 @@ void SemaHLSL::handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL) { } void SemaHLSL::handleVkBindingAttr(Decl *D, const ParsedAttr &AL) { - // The vk::binding attribute only applies to SPIR-V. - if (!getASTContext().getTargetInfo().getTriple().isSPIRV()) - return; - uint32_t Binding = 0; if (!SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(0), Binding)) return; @@ -3775,17 +3770,15 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) { // If the resource array does not have an explicit binding attribute, // create an implicit one. It will be used to transfer implicit binding // order_ID to codegen. - if (!VD->hasAttr()) { - HLSLResourceBindingAttr *RBA = VD->getAttr(); - if (!RBA || !RBA->hasRegisterSlot()) { - uint32_t OrderID = getNextImplicitBindingOrderID(); - if (RBA) - RBA->setImplicitBindingOrderID(OrderID); - else - addImplicitBindingAttrToDecl( - SemaRef, VD, getRegisterType(getResourceArrayHandleType(VD)), - OrderID); - } + ResourceBindingAttrs Binding(VD); + if (!Binding.isExplicit()) { + uint32_t OrderID = getNextImplicitBindingOrderID(); + if (Binding.hasBinding()) + Binding.setImplicitOrderID(OrderID); + else + addImplicitBindingAttrToDecl( + SemaRef, VD, getRegisterType(getResourceArrayHandleType(VD)), + OrderID); } } } diff --git a/clang/test/AST/HLSL/resource_binding_attr.hlsl b/clang/test/AST/HLSL/resource_binding_attr.hlsl index c6d93b991fbfc..2de06741cfd46 100644 --- a/clang/test/AST/HLSL/resource_binding_attr.hlsl +++ b/clang/test/AST/HLSL/resource_binding_attr.hlsl @@ -92,9 +92,8 @@ cbuffer CB3 { StructuredBuffer SB[10]; // CHECK: VarDecl {{.*}} SB2 'StructuredBuffer[10]' +// CHECK: HLSLVkBindingAttr {{.*}} 2 0 // DXIL: HLSLResourceBindingAttr {{.*}} Implicit -// DXIL-NOT: HLSLVkBindingAttr -// SPV: HLSLVkBindingAttr {{.*}} 2 0 // SPV-NOT: HLSLResourceBindingAttr {{.*}} Implicit [[vk::binding(2)]] StructuredBuffer SB2[10]; diff --git a/clang/test/AST/HLSL/vk_binding_attr.hlsl b/clang/test/AST/HLSL/vk_binding_attr.hlsl index d08165d7c593d..13e7544eb672c 100644 --- a/clang/test/AST/HLSL/vk_binding_attr.hlsl +++ b/clang/test/AST/HLSL/vk_binding_attr.hlsl @@ -10,8 +10,7 @@ // SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 102 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0 -// SPV: HLSLVkBindingAttr {{.*}} 23 102 -// DXIL-NOT: HLSLVkBindingAttr +// CHECK: HLSLVkBindingAttr {{.*}} 23 102 [[vk::binding(23, 102)]] StructuredBuffer Buf; // CHECK: VarDecl {{.*}} Buf2 'StructuredBuffer':'hlsl::StructuredBuffer' @@ -23,8 +22,7 @@ // SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 1 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 23 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 102 -// SPV: HLSLVkBindingAttr {{.*}} 14 1 -// DXIL-NOT: HLSLVkBindingAttr +// CHECK: HLSLVkBindingAttr {{.*}} 14 1 // CHECK: HLSLResourceBindingAttr {{.*}} "t23" "space102" [[vk::binding(14, 1)]] StructuredBuffer Buf2 : register(t23, space102); @@ -37,15 +35,13 @@ // SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 23 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 102 -// SPV: HLSLVkBindingAttr {{.*}} 14 0 -// DXIL-NOT: HLSLVkBindingAttr +// CHECK: HLSLVkBindingAttr {{.*}} 14 0 // CHECK: HLSLResourceBindingAttr {{.*}} "t23" "space102" [[vk::binding(14)]] StructuredBuffer Buf3 : register(t23, space102); // CHECK: HLSLBufferDecl {{.*}} cbuffer CB // CHECK-NEXT: HLSLResourceClassAttr {{.*}} Implicit CBuffer -// SPV-NEXT: HLSLVkBindingAttr {{.*}} 1 2 -// DXIL-NOT: HLSLVkBindingAttr +// CHECK: HLSLVkBindingAttr {{.*}} 1 2 [[vk::binding(1, 2)]] cbuffer CB { float a; } @@ -54,15 +50,14 @@ // CHECK-NEXT: CallExpr {{.*}} 'Buffer':'hlsl::Buffer' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::Buffer (*)(unsigned int, unsigned int, int, unsigned int, const char *)' // SPV-NEXT: DeclRefExpr {{.*}} 'hlsl::Buffer (unsigned int, unsigned int, int, unsigned int, const char *)' -// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'Buffer (unsigned int, unsigned int, int, unsigned int, const char *)' +// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::Buffer (unsigned int, unsigned int, int, unsigned int, const char *)' // SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 24 // SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 103 -// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::Buffer (unsigned int, unsigned int, int, unsigned int, const char *)' -// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromImplicitBinding' 'Buffer (unsigned int, unsigned int, int, unsigned int, const char *)' +// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::Buffer (unsigned int, unsigned int, int, unsigned int, const char *)' +// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromImplicitBinding' 'hlsl::Buffer (unsigned int, unsigned int, int, unsigned int, const char *)' // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 2 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0 -// SPV: HLSLVkBindingAttr {{.*}} 24 103 -// DXIL-NOT: HLSLVkBindingAttr +// CHECK: HLSLVkBindingAttr {{.*}} 24 103 [[vk::binding(24, 103)]] Buffer Buf4; // CHECK: VarDecl {{.*}} Buf5 'RWBuffer':'hlsl::RWBuffer>' @@ -76,8 +71,7 @@ // DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromImplicitBinding' 'Buffer (unsigned int, unsigned int, int, unsigned int, const char *)' // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 3 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0 -// SPV: HLSLVkBindingAttr {{.*}} 25 104 -// DXIL-NOT: HLSLVkBindingAttr +// CHECK: HLSLVkBindingAttr {{.*}} 25 104 [[vk::binding(25, 104)]] RWBuffer Buf5; // CHECK: VarDecl {{.*}} Buf6 'RWStructuredBuffer':'hlsl::RWStructuredBuffer' @@ -91,6 +85,5 @@ // DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::RWStructuredBuffer (unsigned int, unsigned int, int, unsigned int, const char *)' // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 4 // DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0 -// SPV: HLSLVkBindingAttr {{.*}} 26 105 -// DXIL-NOT: HLSLVkBindingAttr +// CHECK: HLSLVkBindingAttr {{.*}} 26 105 [[vk::binding(26, 105)]] RWStructuredBuffer Buf6;