================ @@ -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; ---------------- bogner wrote:
This will likely crash once we add the [ConstantBuffer](https://learn.microsoft.com/en-us/windows/win32/direct3d12/resource-binding-in-hlsl#constant-buffers) template syntax, since we'll be able to have: ```hlsl struct S { float4 g_MaxThreadIter; float4 g_Window; }; ConstantBuffer<S> cb0 : register(b0); ``` We should at the very least put a TODO here, but maybe if we can drive cbuffer/tbuffer from attributes we could just do the right thing already? 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