================ @@ -84,6 +84,124 @@ void addRootSignature(llvm::dxbc::RootSignatureVersion RootSigVer, RootSignatureValMD->addOperand(MDVals); } +// If the specified expr is a simple decay from an array to pointer, +// return the array subexpression. Otherwise, return nullptr. +static const Expr *getSubExprFromArrayDecayOperand(const Expr *E) { + const auto *CE = dyn_cast<CastExpr>(E); + if (!CE || CE->getCastKind() != CK_ArrayToPointerDecay) + return nullptr; + return CE->getSubExpr(); +} + +// 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 = getSubExprFromArrayDecayOperand(ASE->getBase()); + 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(const clang::Type *Ty) { + assert(Ty->isArrayType() && "expected array type"); + if (Ty->isIncompleteArrayType()) + return -1; + int Size = 1; + while (const auto *CAT = dyn_cast<ConstantArrayType>(Ty)) { + Size *= CAT->getSExtSize(); + Ty = CAT->getArrayElementTypeNoTypeQual(); + } + return Size; +} + +// Find constructor decl for a specific resource record type and binding +// (implicit vs. explicit). The constructor has 6 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) { + SmallVector<QualType> 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; + ParmVarDecl **ParmIt = Ctor->param_begin(); + QualType *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) { + std::string Str(BaseName); + std::string GlobalName(Str + ".str"); + return CGM.GetAddrOfConstantCString(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) { ---------------- alsepkow wrote:
Given the assert, if its not a VkBinding then it must be an RBA? So, this could just be an else block without the check. https://github.com/llvm/llvm-project/pull/152454 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits