================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits