================ @@ -2576,3 +2576,162 @@ void SemaHLSL::processExplicitBindingsOnDecl(VarDecl *VD) { } } } + +static bool CastInitializer(Sema &S, ASTContext &Ctx, Expr *E, + llvm::SmallVectorImpl<Expr *> &List, + llvm::SmallVectorImpl<QualType> &DestTypes) { + if (List.size() >= DestTypes.size()) + return false; + InitializedEntity Entity = + InitializedEntity::InitializeParameter(Ctx, DestTypes[List.size()], false); + ExprResult Res = + S.PerformCopyInitialization(Entity, E->getBeginLoc(), E); + if (Res.isInvalid()) + return false; + Expr *Init = Res.get(); + List.push_back(Init); + return true; +} + +static void BuildIntializerList(Sema &S, ASTContext &Ctx, Expr *E, + llvm::SmallVectorImpl<Expr *> &List, + llvm::SmallVectorImpl<QualType> &DestTypes, + bool &ExcessInits) { + if (List.size() >= DestTypes.size()) { + ExcessInits = true; + return; + } + + // If this is an initialization list, traverse the sub initializers. + if (auto *Init = dyn_cast<InitListExpr>(E)) { + for (auto *SubInit : Init->inits()) + BuildIntializerList(S, Ctx, SubInit, List, DestTypes, ExcessInits); + return; + } + + // If this is a scalar type, just enqueue the expression. + QualType Ty = E->getType(); + if (Ty->isScalarType()) { + (void)CastInitializer(S, Ctx, E, List, DestTypes); + return; + } + + if (auto *ATy = Ty->getAs<VectorType>()) { + uint64_t Size = ATy->getNumElements(); + + if (List.size() + Size > DestTypes.size()) { + ExcessInits = true; + return; + } + QualType SizeTy = Ctx.getSizeType(); + uint64_t SizeTySize = Ctx.getTypeSize(SizeTy); + for (uint64_t I = 0; I < Size; ++I) { + auto *Idx = IntegerLiteral::Create(Ctx, llvm::APInt(SizeTySize, I), + SizeTy, SourceLocation()); + + ExprResult ElExpr = S.CreateBuiltinArraySubscriptExpr( + E, E->getBeginLoc(), Idx, E->getEndLoc()); + if (ElExpr.isInvalid()) + return; + if (!CastInitializer(S, Ctx, ElExpr.get(), List, DestTypes)) + return; + } + return; + } + + if (auto *VTy = dyn_cast<ConstantArrayType>(Ty.getTypePtr())) { + uint64_t Size = VTy->getZExtSize(); + QualType SizeTy = Ctx.getSizeType(); + uint64_t SizeTySize = Ctx.getTypeSize(SizeTy); + for (uint64_t I = 0; I < Size; ++I) { + auto *Idx = IntegerLiteral::Create(Ctx, llvm::APInt(SizeTySize, I), + SizeTy, SourceLocation()); + ExprResult ElExpr = S.CreateBuiltinArraySubscriptExpr( + E, E->getBeginLoc(), Idx, E->getEndLoc()); + if (ElExpr.isInvalid()) + return; + BuildIntializerList(S, Ctx, ElExpr.get(), List, DestTypes, ExcessInits); + } + return; + } + + if (auto *RTy = Ty->getAs<RecordType>()) { + for (auto *FD : RTy->getDecl()->fields()) { ---------------- hekota wrote:
What if the record has a base class with additional fields? I believe `fields()` iterates over the fields on this class but not base class fields. https://github.com/llvm/llvm-project/pull/123141 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits