@@ -71,6 +71,10 @@ static RegisterType getRegisterType(ResourceClass RC) {
7171 llvm_unreachable (" unexpected ResourceClass value" );
7272}
7373
74+ static RegisterType getRegisterType (const HLSLAttributedResourceType *ResTy) {
75+ return getRegisterType (ResTy->getAttrs ().ResourceClass );
76+ }
77+
7478// Converts the first letter of string Slot to RegisterType.
7579// Returns false if the letter does not correspond to a valid register type.
7680static bool convertToRegisterType (StringRef Slot, RegisterType *RT) {
@@ -342,6 +346,16 @@ static bool isResourceRecordTypeOrArrayOf(VarDecl *VD) {
342346 return Ty->isHLSLResourceRecord () || Ty->isHLSLResourceRecordArray ();
343347}
344348
349+ static const HLSLAttributedResourceType *
350+ getResourceArrayHandleType (VarDecl *VD) {
351+ assert (VD->getType ()->isHLSLResourceRecordArray () &&
352+ " expected array of resource records" );
353+ const Type *Ty = VD->getType ()->getUnqualifiedDesugaredType ();
354+ while (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))
355+ Ty = CAT->getArrayElementTypeNoTypeQual ()->getUnqualifiedDesugaredType ();
356+ return HLSLAttributedResourceType::findHandleTypeOnResource (Ty);
357+ }
358+
345359// Returns true if the type is a leaf element type that is not valid to be
346360// included in HLSL Buffer, such as a resource class, empty struct, zero-sized
347361// array, or a builtin intangible type. Returns false it is a valid leaf element
@@ -568,16 +582,13 @@ void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) {
568582 BufDecl->addLayoutStruct (LS);
569583}
570584
571- static void addImplicitBindingAttrToBuffer (Sema &S, HLSLBufferDecl *BufDecl,
572- uint32_t ImplicitBindingOrderID) {
573- RegisterType RT =
574- BufDecl->isCBuffer () ? RegisterType::CBuffer : RegisterType::SRV;
585+ static void addImplicitBindingAttrToDecl (Sema &S, Decl *D, RegisterType RT,
586+ uint32_t ImplicitBindingOrderID) {
575587 auto *Attr =
576588 HLSLResourceBindingAttr::CreateImplicit (S.getASTContext (), " " , " 0" , {});
577- std::optional<unsigned > RegSlot;
578- Attr->setBinding (RT, RegSlot, 0 );
589+ Attr->setBinding (RT, std::nullopt , 0 );
579590 Attr->setImplicitBindingOrderID (ImplicitBindingOrderID);
580- BufDecl ->addAttr (Attr);
591+ D ->addAttr (Attr);
581592}
582593
583594// Handle end of cbuffer/tbuffer declaration
@@ -600,7 +611,10 @@ void SemaHLSL::ActOnFinishBuffer(Decl *Dcl, SourceLocation RBrace) {
600611 if (RBA)
601612 RBA->setImplicitBindingOrderID (OrderID);
602613 else
603- addImplicitBindingAttrToBuffer (SemaRef, BufDecl, OrderID);
614+ addImplicitBindingAttrToDecl (SemaRef, BufDecl,
615+ BufDecl->isCBuffer () ? RegisterType::CBuffer
616+ : RegisterType::SRV,
617+ OrderID);
604618 }
605619
606620 SemaRef.PopDeclContext ();
@@ -1906,7 +1920,7 @@ static bool DiagnoseLocalRegisterBinding(Sema &S, SourceLocation &ArgLoc,
19061920 if (const HLSLAttributedResourceType *AttrResType =
19071921 HLSLAttributedResourceType::findHandleTypeOnResource (
19081922 VD->getType ().getTypePtr ())) {
1909- if (RegType == getRegisterType (AttrResType-> getAttrs (). ResourceClass ))
1923+ if (RegType == getRegisterType (AttrResType))
19101924 return true ;
19111925
19121926 S.Diag (D->getLocation (), diag::err_hlsl_binding_type_mismatch)
@@ -2439,8 +2453,8 @@ void SemaHLSL::ActOnEndOfTranslationUnit(TranslationUnitDecl *TU) {
24392453 HLSLBufferDecl *DefaultCBuffer = HLSLBufferDecl::CreateDefaultCBuffer (
24402454 SemaRef.getASTContext (), SemaRef.getCurLexicalContext (),
24412455 DefaultCBufferDecls);
2442- addImplicitBindingAttrToBuffer (SemaRef, DefaultCBuffer,
2443- getNextImplicitBindingOrderID ());
2456+ addImplicitBindingAttrToDecl (SemaRef, DefaultCBuffer, RegisterType::CBuffer ,
2457+ getNextImplicitBindingOrderID ());
24442458 SemaRef.getCurLexicalContext ()->addDecl (DefaultCBuffer);
24452459 createHostLayoutStructForBuffer (SemaRef, DefaultCBuffer);
24462460
@@ -3640,6 +3654,24 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
36403654
36413655 // process explicit bindings
36423656 processExplicitBindingsOnDecl (VD);
3657+
3658+ if (VD->getType ()->isHLSLResourceRecordArray ()) {
3659+ // If the resource array does not have an explicit binding attribute,
3660+ // create an implicit one. It will be used to transfer implicit binding
3661+ // order_ID to codegen.
3662+ if (!VD->hasAttr <HLSLVkBindingAttr>()) {
3663+ HLSLResourceBindingAttr *RBA = VD->getAttr <HLSLResourceBindingAttr>();
3664+ if (!RBA || !RBA->hasRegisterSlot ()) {
3665+ uint32_t OrderID = getNextImplicitBindingOrderID ();
3666+ if (RBA)
3667+ RBA->setImplicitBindingOrderID (OrderID);
3668+ else
3669+ addImplicitBindingAttrToDecl (
3670+ SemaRef, VD, getRegisterType (getResourceArrayHandleType (VD)),
3671+ OrderID);
3672+ }
3673+ }
3674+ }
36433675 }
36443676
36453677 deduceAddressSpace (VD);
0 commit comments