================ @@ -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) { + + if (VD) { + const CXXRecordDecl *TheRecordDecl = getRecordDeclFromVarDecl(VD); + if (!TheRecordDecl) + return nullptr; + + // the resource class attr could be on the record decl itself or on one of + // its fields (the resource handle, most commonly) + const auto *Attr = TheRecordDecl->getAttr<HLSLResourceClassAttr>(); + if (!Attr) { + for (auto *FD : TheRecordDecl->fields()) { + Attr = FD->getAttr<HLSLResourceClassAttr>(); + if (Attr) + break; + } + } + return Attr; + } else if (CBufferOrTBuffer) { + const auto *Attr = CBufferOrTBuffer->getAttr<HLSLResourceClassAttr>(); + return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +const HLSLResourceAttr * +getHLSLResourceAttrFromEitherDecl(VarDecl *VD, + HLSLBufferDecl *CBufferOrTBuffer) { + + if (VD) { + const CXXRecordDecl *TheRecordDecl = getRecordDeclFromVarDecl(VD); + if (!TheRecordDecl) + return nullptr; + + // the resource attr could be on the record decl itself or on one of + // its fields (the resource handle, most commonly) + const auto *Attr = TheRecordDecl->getAttr<HLSLResourceAttr>(); + if (!Attr) { + for (auto *FD : TheRecordDecl->fields()) { + Attr = FD->getAttr<HLSLResourceAttr>(); + if (Attr) + break; + } + } + return Attr; + } else if (CBufferOrTBuffer) { + const auto *Attr = CBufferOrTBuffer->getAttr<HLSLResourceAttr>(); + return Attr; + } + llvm_unreachable("one of the two conditions should be true."); + return nullptr; +} + +void traverseType(QualType TheQualTy, RegisterBindingFlags &Flags) { ---------------- bob80905 wrote:
Changed it to `setFlagsFromType`, hopefully a little clearer. https://github.com/llvm/llvm-project/pull/97103 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits