[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