@@ -689,51 +689,22 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
689689 }
690690
691691 llvm::DenseMap<const ValueDecl *, StorageLocation *> FieldLocs;
692-
693- // This only contains the direct fields for the given type.
694- std::vector<const FieldDecl *> FieldsForInit = getFieldsForInitListExpr (S);
695-
696- // `S->inits()` contains all the initializer expressions, including the
697- // ones for direct base classes.
698- ArrayRef<Expr *> Inits = S->inits ();
699- size_t InitIdx = 0 ;
700-
701- // Unions initialized with an empty initializer list need special treatment.
702- // For structs/classes initialized with an empty initializer list, Clang
703- // puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for unions,
704- // it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves.
705- std::optional<ImplicitValueInitExpr> ImplicitValueInitForUnion;
706- SmallVector<Expr *> InitsForUnion;
707- if (S->getType ()->isUnionType () && Inits.empty ()) {
708- assert (FieldsForInit.size () == 1 );
709- ImplicitValueInitForUnion.emplace (FieldsForInit.front ()->getType ());
710- InitsForUnion.push_back (&*ImplicitValueInitForUnion);
711- Inits = InitsForUnion;
712- }
713-
714- // Initialize base classes.
715- if (auto * R = S->getType ()->getAsCXXRecordDecl ()) {
716- assert (FieldsForInit.size () + R->getNumBases () == Inits.size ());
717- for ([[maybe_unused]] const CXXBaseSpecifier &Base : R->bases ()) {
718- assert (InitIdx < Inits.size ());
719- auto Init = Inits[InitIdx++];
720- assert (Base.getType ().getCanonicalType () ==
721- Init->getType ().getCanonicalType ());
722- auto *BaseVal = Env.get <RecordValue>(*Init);
723- if (!BaseVal)
724- BaseVal = cast<RecordValue>(Env.createValue (Init->getType ()));
725- // Take ownership of the fields of the `RecordValue` for the base class
726- // and incorporate them into the "flattened" set of fields for the
727- // derived class.
728- auto Children = BaseVal->getLoc ().children ();
729- FieldLocs.insert (Children.begin (), Children.end ());
730- }
731- }
732-
733- assert (FieldsForInit.size () == Inits.size () - InitIdx);
734- for (auto Field : FieldsForInit) {
735- assert (InitIdx < Inits.size ());
736- auto Init = Inits[InitIdx++];
692+ RecordInitListHelper InitListHelper (S);
693+
694+ for (auto [Base, Init] : InitListHelper.base_inits ()) {
695+ assert (Base->getType ().getCanonicalType () ==
696+ Init->getType ().getCanonicalType ());
697+ auto *BaseVal = Env.get <RecordValue>(*Init);
698+ if (!BaseVal)
699+ BaseVal = cast<RecordValue>(Env.createValue (Init->getType ()));
700+ // Take ownership of the fields of the `RecordValue` for the base class
701+ // and incorporate them into the "flattened" set of fields for the
702+ // derived class.
703+ auto Children = BaseVal->getLoc ().children ();
704+ FieldLocs.insert (Children.begin (), Children.end ());
705+ }
706+
707+ for (auto [Field, Init] : InitListHelper.field_inits ()) {
737708 assert (
738709 // The types are same, or
739710 Field->getType ().getCanonicalType ().getUnqualifiedType () ==
0 commit comments