================ @@ -84,6 +85,111 @@ void addRootSignature(llvm::dxbc::RootSignatureVersion RootSigVer, RootSignatureValMD->addOperand(MDVals); } +// Find array variable declaration from nested array subscript AST nodes +static const ValueDecl *getArrayDecl(const ArraySubscriptExpr *ASE) { + const Expr *E = nullptr; + while (ASE != nullptr) { + E = ASE->getBase()->IgnoreImpCasts(); + if (!E) + return nullptr; + ASE = dyn_cast<ArraySubscriptExpr>(E); + } + if (const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(E)) + return DRE->getDecl(); + return nullptr; +} + +// Get the total size of the array, or -1 if the array is unbounded. +static int getTotalArraySize(ASTContext &AST, const clang::Type *Ty) { + Ty = Ty->getUnqualifiedDesugaredType(); + assert(Ty->isArrayType() && "expected array type"); + if (Ty->isIncompleteArrayType()) + return -1; + return AST.getConstantArrayElementCount(cast<ConstantArrayType>(Ty)); +} + +// Find constructor decl for a specific resource record type and binding +// (implicit vs. explicit). The constructor has 5 parameters. +// For explicit binding the signature is: +// void(unsigned, unsigned, int, unsigned, const char *). +// For implicit binding the signature is: +// void(unsigned, int, unsigned, unsigned, const char *). +static CXXConstructorDecl *findResourceConstructorDecl(ASTContext &AST, + QualType ResTy, + bool ExplicitBinding) { + std::array<QualType, 5> ExpParmTypes = { + AST.UnsignedIntTy, AST.UnsignedIntTy, AST.UnsignedIntTy, + AST.UnsignedIntTy, AST.getPointerType(AST.CharTy.withConst())}; + ExpParmTypes[ExplicitBinding ? 2 : 1] = AST.IntTy; + + CXXRecordDecl *ResDecl = ResTy->getAsCXXRecordDecl(); + for (auto *Ctor : ResDecl->ctors()) { + if (Ctor->getNumParams() != ExpParmTypes.size()) + continue; + auto *ParmIt = Ctor->param_begin(); + auto ExpTyIt = ExpParmTypes.begin(); + for (; ParmIt != Ctor->param_end() && ExpTyIt != ExpParmTypes.end(); + ++ParmIt, ++ExpTyIt) { + if ((*ParmIt)->getType() != *ExpTyIt) + break; + } + if (ParmIt == Ctor->param_end()) + return Ctor; + } + llvm_unreachable("did not find constructor for resource class"); +} + +static Value *buildNameForResource(llvm::StringRef BaseName, + CodeGenModule &CGM) { + llvm::SmallString<64> GlobalName = {BaseName, ".str"}; + return CGM.GetAddrOfConstantCString(BaseName.str(), GlobalName.c_str()) + .getPointer(); +} + +static void createResourceCtorArgs(CodeGenModule &CGM, CXXConstructorDecl *CD, + llvm::Value *ThisPtr, llvm::Value *Range, + llvm::Value *Index, StringRef Name, + HLSLResourceBindingAttr *RBA, + HLSLVkBindingAttr *VkBinding, + CallArgList &Args) { + assert((VkBinding || RBA) && "at least one a binding attribute expected"); + + std::optional<uint32_t> RegisterSlot; + uint32_t SpaceNo = 0; + if (VkBinding) { + RegisterSlot = VkBinding->getBinding(); + SpaceNo = VkBinding->getSet(); + } else { + if (RBA->hasRegisterSlot()) + RegisterSlot = RBA->getSlotNumber(); + SpaceNo = RBA->getSpaceNumber(); + } + + ASTContext &AST = CD->getASTContext(); + Value *NameStr = buildNameForResource(Name, CGM); + Value *Space = llvm::ConstantInt::get(CGM.IntTy, SpaceNo); + + Args.add(RValue::get(ThisPtr), CD->getThisType()); + if (RegisterSlot.has_value()) { + // explicit binding + auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, RegisterSlot.value()); + Args.add(RValue::get(RegSlot), AST.UnsignedIntTy); + Args.add(RValue::get(Space), AST.UnsignedIntTy); + Args.add(RValue::get(Range), AST.IntTy); + Args.add(RValue::get(Index), AST.UnsignedIntTy); + + } else { + // implicit binding + auto *OrderID = + llvm::ConstantInt::get(CGM.IntTy, RBA->getImplicitBindingOrderID()); ---------------- shafik wrote:
This unconditional access of `RBA` looks incorrect. In the first `if/else` statements you know `RBA` is not `nullptr` b/c `VkBinding` is nullptr but in this set that is not obviously true since `RegisterSlot` is set in both branches of the previous `if/else` statement pair. CC @llvm-beanz https://github.com/llvm/llvm-project/pull/152454 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits