[clang] [HLSL] Collect explicit resource binding information (PR #111203)
Damyan Pepper via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 16 14:08:26 PDT 2024
================
@@ -985,88 +1034,85 @@ 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;
+// 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());
- }
+ if (const HLSLAttributedResourceType *AttrResType =
+ findHandleTypeOnResource(Ty)) {
+ // Add a new DeclBindingInfo to Bindings if it does not already exist
+ ResourceClass RC = AttrResType->getAttrs().ResourceClass;
+ DeclBindingInfo *DBI = Bindings.getDeclBindingInfo(VD, RC);
+ if (!DBI)
----------------
damyanp wrote:
At first glance something seems off about that, but without getting the actual array / size implementation in there it's hard to tell.
If there's no test coverage that exercises this case then it might be better to remove the `if` guard so that it doesn't accidentally mask some other problem we weren't expecting.
https://github.com/llvm/llvm-project/pull/111203
More information about the cfe-commits
mailing list