@@ -27,15 +27,21 @@ using namespace namelookup;
2727
2828ImportSet::ImportSet (bool hasHeaderImportModule,
2929 ArrayRef<ImportedModule> topLevelImports,
30- ArrayRef<ImportedModule> transitiveImports)
30+ ArrayRef<ImportedModule> transitiveImports,
31+ ArrayRef<ImportedModule> transitiveSwiftOnlyImports)
3132 : HasHeaderImportModule(hasHeaderImportModule),
3233 NumTopLevelImports(topLevelImports.size()),
33- NumTransitiveImports(transitiveImports.size()) {
34+ NumTransitiveImports(transitiveImports.size()),
35+ NumTransitiveSwiftOnlyImports(transitiveSwiftOnlyImports.size()) {
3436 auto buffer = getTrailingObjects<ImportedModule>();
3537 std::uninitialized_copy (topLevelImports.begin (), topLevelImports.end (),
3638 buffer);
3739 std::uninitialized_copy (transitiveImports.begin (), transitiveImports.end (),
3840 buffer + topLevelImports.size ());
41+ std::uninitialized_copy (transitiveSwiftOnlyImports.begin (),
42+ transitiveSwiftOnlyImports.end (),
43+ buffer + topLevelImports.size () +
44+ transitiveImports.size ());
3945
4046#ifndef NDEBUG
4147 llvm::SmallDenseSet<ImportedModule, 8 > unique;
@@ -47,6 +53,15 @@ ImportSet::ImportSet(bool hasHeaderImportModule,
4753 auto result = unique.insert (import ).second ;
4854 assert (result && " Duplicate imports in import set" );
4955 }
56+
57+ unique.clear ();
58+ for (auto import : topLevelImports) {
59+ unique.insert (import );
60+ }
61+ for (auto import : transitiveSwiftOnlyImports) {
62+ auto result = unique.insert (import ).second ;
63+ assert (result && " Duplicate imports in import set" );
64+ }
5065#endif
5166}
5267
@@ -82,10 +97,14 @@ void ImportSet::dump() const {
8297}
8398
8499static void collectExports (ImportedModule next,
85- SmallVectorImpl<ImportedModule> &stack) {
100+ SmallVectorImpl<ImportedModule> &stack,
101+ bool onlySwiftExports) {
86102 SmallVector<ImportedModule, 4 > exports;
87103 next.importedModule ->getImportedModulesForLookup (exports);
88104 for (auto exported : exports) {
105+ if (onlySwiftExports && exported.importedModule ->isNonSwiftModule ())
106+ continue ;
107+
89108 if (next.accessPath .empty ())
90109 stack.push_back (exported);
91110 else if (exported.accessPath .empty ()) {
@@ -135,7 +154,7 @@ ImportCache::getImportSet(ASTContext &ctx,
135154
136155 SmallVector<ImportedModule, 4 > stack;
137156 for (auto next : topLevelImports) {
138- collectExports (next, stack);
157+ collectExports (next, stack, /* onlySwiftExports */ false );
139158 }
140159
141160 while (!stack.empty ()) {
@@ -148,7 +167,26 @@ ImportCache::getImportSet(ASTContext &ctx,
148167 if (next.importedModule == headerImportModule)
149168 hasHeaderImportModule = true ;
150169
151- collectExports (next, stack);
170+ collectExports (next, stack, /* onlySwiftExports*/ false );
171+ }
172+
173+ // Now collect transitive imports through Swift reexported imports only.
174+ SmallVector<ImportedModule, 4 > transitiveSwiftOnlyImports;
175+ visited.clear ();
176+ stack.clear ();
177+ for (auto next : topLevelImports) {
178+ if (!visited.insert (next).second )
179+ continue ;
180+ collectExports (next, stack, /* onlySwiftExports*/ true );
181+ }
182+
183+ while (!stack.empty ()) {
184+ auto next = stack.pop_back_val ();
185+ if (!visited.insert (next).second )
186+ continue ;
187+
188+ transitiveSwiftOnlyImports.push_back (next);
189+ collectExports (next, stack, /* onlySwiftExports*/ true );
152190 }
153191
154192 // Find the insert position again, in case the above traversal invalidated
@@ -157,12 +195,15 @@ ImportCache::getImportSet(ASTContext &ctx,
157195 if (ImportSet *result = ImportSets.FindNodeOrInsertPos (ID, InsertPos))
158196 return *result;
159197
160- size_t bytes = ImportSet::totalSizeToAlloc<ImportedModule>(topLevelImports.size () + transitiveImports.size ());
198+ size_t bytes = ImportSet::totalSizeToAlloc<ImportedModule>(
199+ topLevelImports.size () + transitiveImports.size () +
200+ transitiveSwiftOnlyImports.size ());
161201 void *mem = ctx.Allocate (bytes, alignof (ImportSet), AllocationArena::Permanent);
162202
163203 auto *result = new (mem) ImportSet (hasHeaderImportModule,
164204 topLevelImports,
165- transitiveImports);
205+ transitiveImports,
206+ transitiveSwiftOnlyImports);
166207 ImportSets.InsertNode (result, InsertPos);
167208
168209 return *result;
@@ -249,6 +290,36 @@ ImportCache::getAllVisibleAccessPaths(const ModuleDecl *mod,
249290 return result;
250291}
251292
293+ bool ImportCache::isImportedByViaSwiftOnly (const ModuleDecl *mod,
294+ const DeclContext *dc) {
295+ dc = dc->getModuleScopeContext ();
296+ if (dc->getParentModule ()->isNonSwiftModule ())
297+ return false ;
298+
299+ auto &ctx = mod->getASTContext ();
300+ auto key = std::make_pair (mod, dc);
301+ auto found = SwiftOnlyCache.find (key);
302+ if (found != SwiftOnlyCache.end ()) {
303+ if (ctx.Stats )
304+ ++ctx.Stats ->getFrontendCounters ().ModuleVisibilityCacheHit ;
305+ return found->second ;
306+ }
307+
308+ if (ctx.Stats )
309+ ++ctx.Stats ->getFrontendCounters ().ModuleVisibilityCacheMiss ;
310+
311+ bool result = false ;
312+ for (auto next : getImportSet (dc).getTransitiveSwiftOnlyImports ()) {
313+ if (next.importedModule == mod) {
314+ result = true ;
315+ break ;
316+ }
317+ }
318+
319+ SwiftOnlyCache[key] = result;
320+ return result;
321+ }
322+
252323ArrayRef<ImportPath::Access>
253324ImportCache::getAllAccessPathsNotShadowedBy (const ModuleDecl *mod,
254325 const ModuleDecl *other,
@@ -307,7 +378,7 @@ ImportCache::getAllAccessPathsNotShadowedBy(const ModuleDecl *mod,
307378 accessPaths.push_back (next.accessPath );
308379 }
309380
310- collectExports (next, stack);
381+ collectExports (next, stack, /* onlySwiftExports */ false );
311382 }
312383
313384 auto result = allocateArray (ctx, accessPaths);
0 commit comments