@@ -1776,78 +1776,118 @@ void ModuleDecl::getDeclaredCrossImportBystanders(
1776
1776
otherModules.push_back (std::get<0 >(pair));
1777
1777
}
1778
1778
1779
- using TransitiveOverlays =
1780
- llvm::SmallDenseMap<ModuleDecl *, std::pair<Identifier, ModuleDecl *>, 1 >;
1781
-
1782
- static void populateTransitiveCrossImports (ModuleDecl *base,
1783
- TransitiveOverlays &result) {
1784
- if (!result.empty () || !base->mightDeclareCrossImportOverlays ())
1785
- return ;
1786
-
1787
- SmallVector<Identifier, 1 > bystanders;
1788
- SmallVector<Identifier, 1 > overlays;
1779
+ void ModuleDecl::findDeclaredCrossImportOverlaysTransitive (
1780
+ SmallVectorImpl<ModuleDecl *> &overlayModules) {
1789
1781
SmallVector<ModuleDecl *, 1 > worklist;
1790
- SourceLoc diagLoc; // ignored
1782
+ SmallPtrSet<ModuleDecl *, 1 > seen;
1783
+ SourceLoc unused;
1791
1784
1792
- worklist.push_back (base );
1785
+ worklist.push_back (this );
1793
1786
while (!worklist.empty ()) {
1794
1787
ModuleDecl *current = worklist.back ();
1795
1788
worklist.pop_back ();
1796
- if (!current->mightDeclareCrossImportOverlays ())
1797
- continue ;
1798
- bystanders.clear ();
1799
- current->getDeclaredCrossImportBystanders (bystanders);
1800
- for (Identifier bystander: bystanders) {
1801
- overlays.clear ();
1802
- current->findDeclaredCrossImportOverlays (bystander, overlays, diagLoc);
1803
- for (Identifier overlay: overlays) {
1804
- if (!overlay.str ().startswith (" _" ))
1805
- continue ;
1806
- ModuleDecl *overlayMod =
1807
- base->getASTContext ().getModuleByName (overlay.str ());
1808
- if (!overlayMod)
1809
- continue ;
1810
- if (result.insert ({overlayMod, {bystander, current}}).second )
1811
- worklist.push_back (overlayMod);
1789
+ for (auto &pair: current->declaredCrossImports ) {
1790
+ Identifier &bystander = std::get<0 >(pair);
1791
+ for (auto *file: std::get<1 >(pair)) {
1792
+ auto overlays = file->getOverlayModuleNames (current, unused, bystander);
1793
+ for (Identifier overlay: overlays) {
1794
+ // We don't present non-underscored overlays as part of the underlying
1795
+ // module, so ignore them.
1796
+ if (!overlay.str ().startswith (" _" ))
1797
+ continue ;
1798
+ ModuleDecl *overlayMod =
1799
+ getASTContext ().getModuleByName (overlay.str ());
1800
+ if (!overlayMod)
1801
+ continue ;
1802
+ if (seen.insert (overlayMod).second ) {
1803
+ overlayModules.push_back (overlayMod);
1804
+ worklist.push_back (overlayMod);
1805
+ }
1806
+ }
1812
1807
}
1813
1808
}
1814
1809
}
1815
1810
}
1816
1811
1817
- bool ModuleDecl::isUnderlyingModuleOfCrossImportOverlay (
1818
- const ModuleDecl *overlay ) {
1819
- if (!overlay-> getNameStr (). startswith ( " _ " ) )
1820
- return false ;
1812
+ std::pair<ModuleDecl *, Identifier>
1813
+ ModuleDecl::getDeclaringModuleAndBystander ( ) {
1814
+ if (declaringModuleAndBystander )
1815
+ return *declaringModuleAndBystander ;
1821
1816
1822
- populateTransitiveCrossImports (this , declaredCrossImportsTransitive);
1823
- return declaredCrossImportsTransitive.find (overlay) !=
1824
- declaredCrossImportsTransitive.end ();
1825
- }
1817
+ if (!hasUnderscoredNaming ())
1818
+ return *(declaringModuleAndBystander = {nullptr , Identifier ()});
1826
1819
1827
- void ModuleDecl::getAllBystandersForCrossImportOverlay (
1828
- ModuleDecl *overlay, SmallVectorImpl<Identifier> &bystanders) {
1829
- if (!overlay->getNameStr ().startswith (" _" ))
1830
- return ;
1820
+ // Search the transitive set of imported @_exported modules to see if any have
1821
+ // this module as their overlay.
1822
+ SmallPtrSet<ModuleDecl *, 16 > seen;
1823
+ SmallVector<ModuleDecl::ImportedModule, 16 > imported;
1824
+ SmallVector<ModuleDecl::ImportedModule, 16 > furtherImported;
1825
+ ModuleDecl *overlayModule = this ;
1826
+
1827
+ getImportedModules (imported, ModuleDecl::ImportFilterKind::Public);
1828
+ while (!imported.empty ()) {
1829
+ ModuleDecl *importedModule = std::get<1 >(imported.back ());
1830
+ imported.pop_back ();
1831
+ if (!seen.insert (importedModule).second )
1832
+ continue ;
1833
+
1834
+ using CrossImportMap =
1835
+ llvm::SmallDenseMap<Identifier, SmallVector<OverlayFile *, 1 >>;
1836
+ CrossImportMap &crossImports = importedModule->declaredCrossImports ;
1837
+
1838
+ // If any of MD's cross imports declare this module as its overlay, report
1839
+ // MD as the underlying module.
1840
+ auto ret = std::find_if (crossImports.begin (), crossImports.end (),
1841
+ [&](CrossImportMap::iterator::value_type &pair) {
1842
+ for (OverlayFile *file: std::get<1 >(pair)) {
1843
+ ArrayRef<Identifier> overlays = file->getOverlayModuleNames (
1844
+ importedModule, SourceLoc (), std::get<0 >(pair));
1845
+ if (std::find (overlays.begin (), overlays.end (),
1846
+ overlayModule->getName ()) != overlays.end ())
1847
+ return true ;
1848
+ }
1849
+ return false ;
1850
+ });
1851
+ if (ret != crossImports.end ())
1852
+ return *(declaringModuleAndBystander = {importedModule, ret->first });
1831
1853
1832
- populateTransitiveCrossImports (this , declaredCrossImportsTransitive);
1854
+ if (!importedModule->hasUnderscoredNaming ())
1855
+ continue ;
1833
1856
1834
- auto end = declaredCrossImportsTransitive.end ();
1835
- for (auto i = declaredCrossImportsTransitive.find (overlay);
1836
- i != end;
1837
- i = declaredCrossImportsTransitive.find (i->second .second )) {
1838
- bystanders.push_back (i->second .first );
1857
+ furtherImported.clear ();
1858
+ importedModule->getImportedModules (furtherImported,
1859
+ ModuleDecl::ImportFilterKind::Public);
1860
+ imported.append (furtherImported.begin (), furtherImported.end ());
1839
1861
}
1862
+
1863
+ return *(declaringModuleAndBystander = {nullptr , Identifier ()});
1840
1864
}
1841
1865
1842
- void ModuleDecl::findDeclaredCrossImportOverlaysTransitive (
1843
- SmallVectorImpl<ModuleDecl *> &overlayModules) {
1844
- populateTransitiveCrossImports (this , declaredCrossImportsTransitive);
1845
- std::transform (declaredCrossImportsTransitive.begin (),
1846
- declaredCrossImportsTransitive.end (),
1847
- std::back_inserter (overlayModules),
1848
- [](TransitiveOverlays::iterator::value_type &i) {
1849
- return i.first ;
1850
- });
1866
+ bool ModuleDecl::isCrossImportOverlayOf (ModuleDecl *other) {
1867
+ ModuleDecl *current = this ;
1868
+ while ((current = current->getDeclaringModuleAndBystander ().first )) {
1869
+ if (current == other)
1870
+ return true ;
1871
+ }
1872
+ return false ;
1873
+ }
1874
+
1875
+ ModuleDecl *ModuleDecl::getDeclaringModuleIfCrossImportOverlay () {
1876
+ ModuleDecl *current = this , *declaring = nullptr ;
1877
+ while ((current = current->getDeclaringModuleAndBystander ().first ))
1878
+ declaring = current;
1879
+ return declaring;
1880
+ }
1881
+
1882
+ bool ModuleDecl::getRequiredBystandersIfCrossImportOverlay (
1883
+ ModuleDecl *declaring, SmallVectorImpl<Identifier> &bystanderNames) {
1884
+ auto current = std::make_pair (this , Identifier ());
1885
+ while ((current = current.first ->getDeclaringModuleAndBystander ()).first ) {
1886
+ bystanderNames.push_back (current.second );
1887
+ if (current.first == declaring)
1888
+ return true ;
1889
+ }
1890
+ return false ;
1851
1891
}
1852
1892
1853
1893
namespace {
@@ -2170,32 +2210,6 @@ bool SourceFile::shouldCrossImport() const {
2170
2210
getASTContext ().LangOpts .EnableCrossImportOverlays ;
2171
2211
}
2172
2212
2173
- ModuleDecl*
2174
- SourceFile::getModuleShadowedBySeparatelyImportedOverlay (const ModuleDecl *overlay) {
2175
- if (separatelyImportedOverlaysReversed.empty () &&
2176
- !separatelyImportedOverlays.empty ()) {
2177
- for (auto &entry: separatelyImportedOverlays) {
2178
- ModuleDecl *shadowed = entry.first ;
2179
- for (ModuleDecl *overlay: entry.second ) {
2180
- // If for some reason the same overlay shadows more than one module,
2181
- // pick the one whose name is alphabetically first.
2182
- ModuleDecl *old = separatelyImportedOverlaysReversed[overlay];
2183
- if (!old || shadowed->getNameStr () < old->getNameStr ())
2184
- separatelyImportedOverlaysReversed[overlay] = shadowed;
2185
- }
2186
- }
2187
- }
2188
-
2189
- ModuleDecl *underlying = const_cast <ModuleDecl *>(overlay);
2190
- while (underlying->getNameStr ().startswith (" _" )) {
2191
- auto next = separatelyImportedOverlaysReversed.find (underlying);
2192
- if (next == separatelyImportedOverlaysReversed.end ())
2193
- return nullptr ;
2194
- underlying = std::get<1 >(*next);
2195
- }
2196
- return underlying;
2197
- };
2198
-
2199
2213
void ModuleDecl::clearLookupCache () {
2200
2214
getASTContext ().getImportCache ().clear ();
2201
2215
0 commit comments