@@ -615,39 +615,31 @@ ProjectionPath::subtractPaths(const ProjectionPath &LHS, const ProjectionPath &R
615
615
void
616
616
ProjectionPath::expandTypeIntoLeafProjectionPaths (SILType B, SILModule *Mod,
617
617
ProjectionPathList &Paths) {
618
+
618
619
// Perform a BFS to expand the given type into projectionpath each of
619
620
// which contains 1 field from the type.
620
- ProjectionPathList WorkList ;
621
+ ProjectionPathList Worklist ;
621
622
llvm::SmallVector<Projection, 8 > Projections;
622
623
623
- // Get the first level projection of the current type.
624
- Projection::getFirstLevelAddrProjections (B, *Mod, Projections);
625
- for (auto &AP : Projections) {
626
- ProjectionPath X;
627
- X.Path .push_back (AP);
628
- WorkList.push_back (std::move (X));
629
- }
630
-
631
- // If the BaseType is a leaf node, push a single empty projection path.
632
- if (WorkList.empty ()) {
633
- ProjectionPath P;
634
- Paths.push_back (std::move (P));
635
- return ;
636
- }
637
-
638
- // Keep iterating if the worklist is not empty.
639
- while (!WorkList.empty ()) {
640
- Optional<ProjectionPath> Path = WorkList.pop_back_val ();
641
- SILType ParentTy = Path.getValue ().front ().getType ();
624
+ // Push an empty projection path to get started.
625
+ SILType Ty;
626
+ ProjectionPath P;
627
+ Worklist.push_back (std::move (P));
628
+ do {
629
+ // Get the next level projections based on current projection's type.
630
+ Optional<ProjectionPath> PP = Worklist.pop_back_val ();
631
+ // Get the current type to process, the very first projection path will be
632
+ // empty.
633
+ Ty = PP.getValue ().empty () ? B : PP.getValue ().front ().getType ();
642
634
643
635
// Get the first level projection of the current type.
644
636
Projections.clear ();
645
- Projection::getFirstLevelAddrProjections (ParentTy , *Mod, Projections);
637
+ Projection::getFirstLevelAddrProjections (Ty , *Mod, Projections);
646
638
647
639
// Reached the end of the projection tree, this field can not be expanded
648
640
// anymore.
649
641
if (Projections.empty ()) {
650
- Paths.push_back (std::move (Path .getValue ()));
642
+ Paths.push_back (std::move (PP .getValue ()));
651
643
continue ;
652
644
}
653
645
@@ -668,22 +660,21 @@ ProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod,
668
660
//
669
661
// The worklist would never be empty in this case !.
670
662
//
671
- if (ParentTy .getClassOrBoundGenericClass ()) {
672
- Paths.push_back (std::move (Path .getValue ()));
663
+ if (Ty .getClassOrBoundGenericClass ()) {
664
+ Paths.push_back (std::move (PP .getValue ()));
673
665
continue ;
674
666
}
675
667
676
- // Keep the intermediate nodes as well.
677
- Paths.push_back (std::move (Path.getValue ()));
678
-
679
668
// Keep expanding the location.
680
669
for (auto &P : Projections) {
681
670
ProjectionPath X;
682
671
X.append (P);
683
- X.append (Path .getValue ());
684
- WorkList .push_back (std::move (X));
672
+ X.append (PP .getValue ());
673
+ Worklist .push_back (std::move (X));
685
674
}
686
- }
675
+ // Keep iterating if the worklist is not empty.
676
+ } while (!Worklist.empty ());
677
+
687
678
}
688
679
689
680
void
0 commit comments