@@ -689,51 +689,22 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
689
689
}
690
690
691
691
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 ()) {
737
708
assert (
738
709
// The types are same, or
739
710
Field->getType ().getCanonicalType ().getUnqualifiedType () ==
0 commit comments