================ @@ -1142,3 +1142,85 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { } return false; } + +static void BuildFlattenedTypeList(QualType BaseTy, + llvm::SmallVectorImpl<QualType> &List) { + llvm::SmallVector<QualType, 16> WorkList; + WorkList.push_back(BaseTy); + while (!WorkList.empty()) { + QualType T = WorkList.pop_back_val(); + T = T.getCanonicalType().getUnqualifiedType(); + assert(!isa<MatrixType>(T) && "Matrix types not yet supported in HLSL"); + if (const auto *AT = dyn_cast<ConstantArrayType>(T)) { + llvm::SmallVector<QualType, 16> ElementFields; + // Generally I've avoided recursion in this algorithm, but arrays of + // structs could be time-consuming to flatten and churn through on the + // work list. Hopefully nesting arrays of structs containing arrays + // of structs too many levels deep is unlikely. + BuildFlattenedTypeList(AT->getElementType(), ElementFields); + // Repeat the element's field list n times. + for (uint64_t Ct = 0; Ct < AT->getZExtSize(); ++Ct) + List.insert(List.end(), ElementFields.begin(), ElementFields.end()); + continue; + } + // Vectors can only have element types that are builtin types, so this can + // add directly to the list instead of to the WorkList. + if (const auto *VT = dyn_cast<VectorType>(T)) { + List.insert(List.end(), VT->getNumElements(), VT->getElementType()); + continue; + } + if (const auto *RT = dyn_cast<RecordType>(T)) { + const RecordDecl *RD = RT->getDecl(); + if (RD->isUnion()) { + List.push_back(T); + continue; + } + const CXXRecordDecl *CXXD = dyn_cast<CXXRecordDecl>(RD); + + llvm::SmallVector<QualType, 16> FieldTypes; + if (CXXD && CXXD->isStandardLayout()) + RD = CXXD->getStandardLayoutBaseWithFields(); + + for (const auto *FD : RD->fields()) + FieldTypes.push_back(FD->getType()); + // Reverse the newly added sub-range. + std::reverse(FieldTypes.begin(), FieldTypes.end()); ---------------- llvm-beanz wrote:
It's because of the worklist processing, nothing domain specific. For example, given: ```hlsl struct T { int X; float Y; }; struct V { T t; double D; }; ``` When I build the worklist for `V` it does: * Start with V : Worklist: {V} Result {} * Iterate V's members: Worklist: { T, double } Result {} * _Reverse added members_ : Worklist: { double, T } Result {} * Pop `T` from back() and iterate it's members: Worklist : { double, int, float } Result {} * _Reverse added members_ : Worklist: { double, float, int } Result {} * Pop and record it in the result : Worklist: { double, float} Result { int } * Pop and record it in the result : Worklist: { double } Result { int, float } * Pop and record it in the result : Worklist: { } Result { int, float, double } https://github.com/llvm/llvm-project/pull/102227 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits