[clang] [HLSL] Collect explicit resource binding information (PR #111203)
Justin Bogner via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 15 08:33:55 PDT 2024
================
@@ -2235,3 +2280,107 @@ QualType SemaHLSL::getInoutParameterType(QualType Ty) {
Ty.addRestrict();
return Ty;
}
+
+void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
+ if (VD->hasGlobalStorage()) {
+ // make sure the declaration has a complete type
+ if (SemaRef.RequireCompleteType(
+ VD->getLocation(),
+ SemaRef.getASTContext().getBaseElementType(VD->getType()),
+ diag::err_typecheck_decl_incomplete_type)) {
+ VD->setInvalidDecl();
+ return;
+ }
+
+ // find all resources on decl
+ if (IsIntangibleType(VD->getType()))
+ FindResourcesOnVarDecl(VD);
+
+ // process explicit bindings
+ ProcessExplicitBindingsOnDecl(VD);
+ }
+}
+
+// Walks though the global variable declaration, collects all resource binding
+// requirements and adds them to Bindings
+void SemaHLSL::FindResourcesOnVarDecl(VarDecl *VD) {
+ assert(VD->hasGlobalStorage() && IsIntangibleType(VD->getType()) &&
+ "expected global variable that contains HLSL resource");
+
+ // Cbuffers and Tbuffers are HLSLBufferDecl types
+ if (const HLSLBufferDecl *CBufferOrTBuffer = dyn_cast<HLSLBufferDecl>(VD)) {
+ Bindings.addDeclBindingInfo(VD,
+ CBufferOrTBuffer->isCBuffer()
+ ? ResourceClass::CBuffer
+ : ResourceClass::SRV,
+ 1);
+ return;
+ }
+
+ // Calculate size of array and unwrap
+ int Size = 1;
+ const Type *Ty = VD->getType()->getUnqualifiedDesugaredType();
+ if (Ty->isIncompleteArrayType())
+ Size = -1;
+ while (Ty->isConstantArrayType()) {
+ const ConstantArrayType *CAT = cast<ConstantArrayType>(Ty);
+ Size *= CAT->getSize().getSExtValue();
+ Ty = CAT->getElementType()->getUnqualifiedDesugaredType();
+ }
+
+ // Resource (or array of resources)
+ if (const HLSLAttributedResourceType *AttrResType =
+ FindHandleTypeOnResource(Ty)) {
+ Bindings.addDeclBindingInfo(VD, AttrResType->getAttrs().ResourceClass,
+ Size);
+ return;
+ }
+
+ assert(Size != -1 &&
+ "unbounded arrays of user defined types are not supported");
+
+ // User defined record type
+ if (const RecordType *RT = dyn_cast<RecordType>(Ty))
+ FindResourcesOnUserRecordDecl(VD, RT, Size);
+}
+
+// Walks though the explicit resource binding attributes on the declaration,
+// and makes sure there is a resource that matched the binding and updates
+// DeclBindingInfoLists
+void SemaHLSL::ProcessExplicitBindingsOnDecl(VarDecl *VD) {
+ assert(VD->hasGlobalStorage() && "expected global variable");
+
+ for (Attr *A : VD->attrs()) {
+ HLSLResourceBindingAttr *RBA = dyn_cast<HLSLResourceBindingAttr>(A);
+ if (!RBA)
+ continue;
+
+ RegisterType RT = RBA->getRegisterType();
+ assert(RT != RegisterType::I && RT != RegisterType::Invalid &&
+ "invalid or obsolete register type should never have an attribute "
+ "created");
+
+ // These were already diagnosed earlier
+ if (RT == RegisterType::C) {
+ if (Bindings.hasBindingInfoForDecl(VD))
+ SemaRef.Diag(VD->getLocation(),
+ diag::warn_hlsl_user_defined_type_missing_member)
+ << static_cast<int>(RT);
+ continue;
+ }
----------------
bogner wrote:
If they were diagnosed earlier why are we emitting a diagnostic? Is this comment accurate?
https://github.com/llvm/llvm-project/pull/111203
More information about the cfe-commits
mailing list