[clang] [HLSL] Collect explicit resource binding information (PR #111203)
Justin Bogner via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 16 06:17:06 PDT 2024
================
@@ -985,88 +1034,94 @@ SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) {
return LocInfo;
}
-// get the record decl from a var decl that we expect
-// represents a resource
-static CXXRecordDecl *getRecordDeclFromVarDecl(VarDecl *VD) {
- const Type *Ty = VD->getType()->getPointeeOrArrayElementType();
- assert(Ty && "Resource must have an element type.");
-
- if (Ty->isBuiltinType())
- return nullptr;
-
- CXXRecordDecl *TheRecordDecl = Ty->getAsCXXRecordDecl();
- assert(TheRecordDecl && "Resource should have a resource type declaration.");
- return TheRecordDecl;
-}
-
+// Returns handle type of a resource, if the type is a resource
static const HLSLAttributedResourceType *
-findAttributedResourceTypeOnField(VarDecl *VD) {
- assert(VD != nullptr && "expected VarDecl");
- if (RecordDecl *RD = getRecordDeclFromVarDecl(VD)) {
- for (auto *FD : RD->fields()) {
- if (const HLSLAttributedResourceType *AttrResType =
- dyn_cast<HLSLAttributedResourceType>(FD->getType().getTypePtr()))
- return AttrResType;
+FindHandleTypeOnResource(const Type *Ty) {
+ // If Ty is a resource class, the first field must
+ // be the resource handle of type HLSLAttributedResourceType
+ if (RecordDecl *RD = Ty->getAsCXXRecordDecl()) {
+ if (!RD->fields().empty()) {
+ const auto &FirstFD = RD->fields().begin();
+ return dyn_cast<HLSLAttributedResourceType>(
+ FirstFD->getType().getTypePtr());
}
}
return nullptr;
}
-// Iterate over RecordType fields and return true if any of them matched the
-// register type
-static bool ContainsResourceForRegisterType(Sema &S, const RecordType *RT,
- RegisterType RegType) {
- llvm::SmallVector<const Type *> TypesToScan;
- TypesToScan.emplace_back(RT);
-
- while (!TypesToScan.empty()) {
- const Type *T = TypesToScan.pop_back_val();
- while (T->isArrayType())
- T = T->getArrayElementTypeNoTypeQual();
- if (T->isIntegralOrEnumerationType() || T->isFloatingType()) {
- if (RegType == RegisterType::C)
- return true;
+// Returns handle type of a resource, if the VarDecl is a resource
+static const HLSLAttributedResourceType *
+FindHandleTypeOnResource(const VarDecl *VD) {
+ assert(VD != nullptr && "expected VarDecl");
+ return FindHandleTypeOnResource(VD->getType().getTypePtr());
+}
+
+// Walks though the global variable declaration, collects all resource binding
+// requirements and adds them to Bindings
+void SemaHLSL::collectResourcesOnUserRecordDecl(const VarDecl *VD,
+ const RecordType *RT) {
+ const RecordDecl *RD = RT->getDecl();
+ for (FieldDecl *FD : RD->fields()) {
+ const Type *Ty = FD->getType()->getUnqualifiedDesugaredType();
+
+ // Unwrap arrays
+ // FIXME: Calculate array size while unwrapping
+ assert(!Ty->isIncompleteArrayType() &&
+ "incomplete arrays inside user defined types are not supported");
+ while (Ty->isConstantArrayType()) {
+ const ConstantArrayType *CAT = cast<ConstantArrayType>(Ty);
+ Ty = CAT->getElementType()->getUnqualifiedDesugaredType();
}
- const RecordType *RT = T->getAs<RecordType>();
- if (!RT)
+
+ if (!Ty->isRecordType())
continue;
- const RecordDecl *RD = RT->getDecl();
- for (FieldDecl *FD : RD->fields()) {
- const Type *FieldTy = FD->getType().getTypePtr();
- if (const HLSLAttributedResourceType *AttrResType =
- dyn_cast<HLSLAttributedResourceType>(FieldTy)) {
- ResourceClass RC = AttrResType->getAttrs().ResourceClass;
- if (getRegisterType(RC) == RegType)
- return true;
- } else {
- TypesToScan.emplace_back(FD->getType().getTypePtr());
- }
+ // Field is a resource or array of resources
----------------
bogner wrote:
This comment isn't entirely accurate. At this point we could still have a struct or UDT that isn't a resource, right?
https://github.com/llvm/llvm-project/pull/111203
More information about the cfe-commits
mailing list