@@ -1588,6 +1588,80 @@ void ModuleDecl::getDeclaredCrossImportBystanders(
1588
1588
otherModules.push_back (std::get<0 >(pair));
1589
1589
}
1590
1590
1591
+ using TransitiveOverlays =
1592
+ llvm::SmallDenseMap<ModuleDecl *, std::pair<Identifier, ModuleDecl *>, 1 >;
1593
+
1594
+ static void populateTransitiveCrossImports (ModuleDecl *base,
1595
+ TransitiveOverlays &result) {
1596
+ if (!result.empty () || !base->mightDeclareCrossImportOverlays ())
1597
+ return ;
1598
+
1599
+ SmallVector<Identifier, 1 > bystanders;
1600
+ SmallVector<Identifier, 1 > overlays;
1601
+ SmallVector<ModuleDecl *, 1 > worklist;
1602
+ SourceLoc diagLoc; // ignored
1603
+
1604
+ worklist.push_back (base);
1605
+ while (!worklist.empty ()) {
1606
+ ModuleDecl *current = worklist.back ();
1607
+ worklist.pop_back ();
1608
+ if (!current->mightDeclareCrossImportOverlays ())
1609
+ continue ;
1610
+ bystanders.clear ();
1611
+ current->getDeclaredCrossImportBystanders (bystanders);
1612
+ for (Identifier bystander: bystanders) {
1613
+ overlays.clear ();
1614
+ current->findDeclaredCrossImportOverlays (bystander, overlays, diagLoc);
1615
+ for (Identifier overlay: overlays) {
1616
+ if (!overlay.str ().startswith (" _" ))
1617
+ continue ;
1618
+ ModuleDecl *overlayMod =
1619
+ base->getASTContext ().getModuleByName (overlay.str ());
1620
+ if (!overlayMod)
1621
+ continue ;
1622
+ if (result.insert ({overlayMod, {bystander, current}}).second )
1623
+ worklist.push_back (overlayMod);
1624
+ }
1625
+ }
1626
+ }
1627
+ }
1628
+
1629
+ bool ModuleDecl::isUnderlyingModuleOfCrossImportOverlay (
1630
+ const ModuleDecl *overlay) {
1631
+ if (!overlay->getNameStr ().startswith (" _" ))
1632
+ return false ;
1633
+
1634
+ populateTransitiveCrossImports (this , declaredCrossImportsTransitive);
1635
+ return declaredCrossImportsTransitive.find (overlay) !=
1636
+ declaredCrossImportsTransitive.end ();
1637
+ }
1638
+
1639
+ void ModuleDecl::getAllBystandersForCrossImportOverlay (
1640
+ ModuleDecl *overlay, SmallVectorImpl<Identifier> &bystanders) {
1641
+ if (!overlay->getNameStr ().startswith (" _" ))
1642
+ return ;
1643
+
1644
+ populateTransitiveCrossImports (this , declaredCrossImportsTransitive);
1645
+
1646
+ auto end = declaredCrossImportsTransitive.end ();
1647
+ for (auto i = declaredCrossImportsTransitive.find (overlay);
1648
+ i != end;
1649
+ i = declaredCrossImportsTransitive.find (i->second .second )) {
1650
+ bystanders.push_back (i->second .first );
1651
+ }
1652
+ }
1653
+
1654
+ void ModuleDecl::findDeclaredCrossImportOverlaysTransitive (
1655
+ SmallVectorImpl<ModuleDecl *> &overlayModules) {
1656
+ populateTransitiveCrossImports (this , declaredCrossImportsTransitive);
1657
+ std::transform (declaredCrossImportsTransitive.begin (),
1658
+ declaredCrossImportsTransitive.end (),
1659
+ std::back_inserter (overlayModules),
1660
+ [](TransitiveOverlays::iterator::value_type &i) {
1661
+ return i.first ;
1662
+ });
1663
+ }
1664
+
1591
1665
namespace {
1592
1666
struct OverlayFileContents {
1593
1667
struct Module {
0 commit comments