================ @@ -7334,6 +7334,92 @@ static void handleHLSLShaderAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(NewAttr); } +static void DiagnoseHLSLResourceRegType(Sema &S, SourceLocation &ArgLoc, + Decl *D, StringRef &Slot) { + // Samplers, UAVs, and SRVs are VarDecl types + VarDecl *SamplerUAVOrSRV = dyn_cast<VarDecl>(D); + // Cbuffers and Tbuffers are HLSLBufferDecl types + HLSLBufferDecl *CBufferOrTBuffer = dyn_cast<HLSLBufferDecl>(D); + if (!SamplerUAVOrSRV && !CBufferOrTBuffer) + return; + + llvm::hlsl::ResourceClass DeclResourceClass; + StringRef VarTy = ""; + if (SamplerUAVOrSRV) { + const Type *Ty = SamplerUAVOrSRV->getType()->getPointeeOrArrayElementType(); + if (!Ty) + llvm_unreachable("Resource class must have an element type."); + + if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) { + QualType QT = SamplerUAVOrSRV->getType(); + PrintingPolicy PP = S.getPrintingPolicy(); + std::string typestr = QualType::getAsString(QT.split(), PP); + + if (Slot[0] != 't') + S.Diag(ArgLoc, + diag::err_hlsl_mismatching_register_builtin_type_and_name) + << Slot.substr(0, 1) << typestr << "'t'"; + return; + } + + const CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl(); + if (!TheRecordDecl) + llvm_unreachable( + "Resource class should have a resource type declaration."); + + if (auto TDecl = dyn_cast<ClassTemplateSpecializationDecl>(TheRecordDecl)) + TheRecordDecl = TDecl->getSpecializedTemplate()->getTemplatedDecl(); + TheRecordDecl = TheRecordDecl->getCanonicalDecl(); + const auto *Attr = TheRecordDecl->getAttr<HLSLResourceAttr>(); + if (!Attr) + llvm_unreachable("Resource class should have a resource attribute."); + + DeclResourceClass = Attr->getResourceClass(); + VarTy = TheRecordDecl->getName(); + } else { + DeclResourceClass = llvm::hlsl::ResourceClass::CBuffer; + } + switch (DeclResourceClass) { + case llvm::hlsl::ResourceClass::SRV: { + if (Slot[0] == 't') + return; + break; + } + case llvm::hlsl::ResourceClass::UAV: { + if (Slot[0] == 'u') + return; + break; + } + case llvm::hlsl::ResourceClass::CBuffer: { + // could be CBuffer or TBuffer + if (CBufferOrTBuffer->isCBuffer()) { + VarTy = "cbuffer"; + if (Slot[0] == 'b') + return; + } else { + VarTy = "tbuffer"; + // This isn't an SRV, but we need the diagnostic to emit + // the same binding prefix that would be expected on an SRV. + DeclResourceClass = llvm::hlsl::ResourceClass::SRV; ---------------- bogner wrote:
This comment isn't exactly correct. A `tbuffer` *is* an SRV, we simply don't have a `ClassDecl` with the annotation to get that information from. I wonder if it would be better to put attributes on `HLSLBufferDecl` (perhaps in `SemaHLSL::ActOnStartBuffer`) so that we can drive the two ways of getting here in the same way. https://github.com/llvm/llvm-project/pull/87578 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits