[clang] Implement resource binding type prefix mismatch diagnostic infrastructure (PR #97103)

Joshua Batista via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 15 10:01:03 PDT 2024


================
@@ -459,7 +467,506 @@ void SemaHLSL::handleResourceClassAttr(Decl *D, const ParsedAttr &AL) {
   D->addAttr(HLSLResourceClassAttr::Create(getASTContext(), RC, ArgLoc));
 }
 
-void SemaHLSL::handleResourceBindingAttr(Decl *D, const ParsedAttr &AL) {
+struct RegisterBindingFlags {
+  bool Resource = false;
+  bool UDT = false;
+  bool Other = false;
+  bool Basic = false;
+
+  bool SRV = false;
+  bool UAV = false;
+  bool CBV = false;
+  bool Sampler = false;
+
+  bool ContainsNumeric = false;
+  bool DefaultGlobals = false;
+};
+
+bool isDeclaredWithinCOrTBuffer(const Decl *TheDecl) {
+  if (!TheDecl)
+    return false;
+
+  // Traverse up the parent contexts
+  const DeclContext *context = TheDecl->getDeclContext();
+  if (isa<HLSLBufferDecl>(context)) {
+    return true;
+  }
+
+  return false;
+}
+
+const CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *VD) {
+  const Type *Ty = VD->getType()->getPointeeOrArrayElementType();
+  assert(Ty && "Resource class must have an element type.");
+
+  if (const auto *TheBuiltinTy = dyn_cast<BuiltinType>(Ty))
+    return nullptr;
+
+  const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl();
+  assert(TheRecordDecl &&
+         "Resource class should have a resource type declaration.");
+
+  if (auto TDecl = dyn_cast<ClassTemplateSpecializationDecl>(TheRecordDecl))
+    TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl();
+  TheRecordDecl = TheRecordDecl->getCanonicalDecl();
+  return TheRecordDecl;
+}
+
+const HLSLResourceClassAttr *
+getHLSLResourceClassAttrFromEitherDecl(VarDecl *VD,
+                                       HLSLBufferDecl *CBufferOrTBuffer) {
+
----------------
bob80905 wrote:

Near the top of `DiagnoseHLSLRegisterAttribute`, there's an assert: 
`assert(((TheVarDecl && !CBufferOrTBuffer) || (!TheVarDecl && CBufferOrTBuffer)) && "either TheVarDecl or BufferOrTBuffer should be set");`
It will trigger if both are set. If both are set, there's been some sort of bug or error, because it shouldn't be possible for the decl (called `TheDecl` in that function) to be castable to both a vardecl and an hlslbufferdecl. We expect that `cbuffer` and `tbuffer` are represented with an `HLSLBufferDecl`, and that everything else (e.g, RWBuffer) is represented with a `VarDecl`, and neither are subtypes of each other.

https://github.com/llvm/llvm-project/pull/97103


More information about the cfe-commits mailing list