================ @@ -6358,3 +6359,89 @@ RValue CodeGenFunction::EmitPseudoObjectRValue(const PseudoObjectExpr *E, LValue CodeGenFunction::EmitPseudoObjectLValue(const PseudoObjectExpr *E) { return emitPseudoObjectExpr(*this, E, true, AggValueSlot::ignored()).LV; } + +void CodeGenFunction::FlattenAccessAndType( + Address Addr, QualType AddrType, + SmallVectorImpl<std::pair<Address, llvm::Value *>> &AccessList, + SmallVectorImpl<QualType> &FlatTypes) { + // WorkList is list of type we are processing + the Index List to access + // the field of that type in Addr for use in a GEP + llvm::SmallVector<std::pair<QualType, llvm::SmallVector<llvm::Value *, 4>>, + 16> + WorkList; + llvm::IntegerType *IdxTy = llvm::IntegerType::get(getLLVMContext(), 32); + WorkList.push_back( + {AddrType, + {llvm::ConstantInt::get( + IdxTy, + 0)}}); // Addr should be a pointer so we need to 'dereference' it + + while (!WorkList.empty()) { + std::pair<QualType, llvm::SmallVector<llvm::Value *, 4>> P = + WorkList.pop_back_val(); + QualType T = P.first; + llvm::SmallVector<llvm::Value *, 4> IdxList = P.second; + T = T.getCanonicalType().getUnqualifiedType(); + assert(!isa<MatrixType>(T) && "Matrix types not yet supported in HLSL"); + if (const auto *CAT = dyn_cast<ConstantArrayType>(T)) { + uint64_t Size = CAT->getZExtSize(); + for (int64_t i = Size - 1; i > -1; i--) { + llvm::SmallVector<llvm::Value *, 4> IdxListCopy = IdxList; + IdxListCopy.push_back(llvm::ConstantInt::get(IdxTy, i)); + WorkList.insert(WorkList.end(), {CAT->getElementType(), IdxListCopy}); + } + } else if (const auto *RT = dyn_cast<RecordType>(T)) { + const RecordDecl *Record = RT->getDecl(); + if (Record->isUnion()) { + IdxList.push_back(llvm::ConstantInt::get(IdxTy, 0)); ---------------- llvm-beanz wrote:
This probably doesn't actually work. We should probably disallow flat casts for anything where a union is a member. Just as an example of where this could go wrong: ```c++ union U { int16_t A; int32_t B; }; ``` IIUC, your code as written will load A, which is not the full memory for the union so you may be truncating. Fundamentally these elementwise conversions are probably totally bunk with unions because you don't know the source type to convert from. The only case where this could possibly work is if the union were not to be converted at all. Note: union types aren't currently supported in HLSL, we wanted them for HLSL 2021 but they didn't get implemented in time. It would be nice to support them in Clang, but we probably should restrict where they are used and how they can be used. https://github.com/llvm/llvm-project/pull/118842 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits