@@ -62,23 +62,12 @@ static void findAllImportedClangModules(ASTContext &ctx, StringRef moduleName,
62
62
// / Resolve the direct dependencies of the given module.
63
63
static std::vector<ModuleDependencyID> resolveDirectDependencies (
64
64
CompilerInstance &instance, ModuleDependencyID module ,
65
- ModuleDependenciesCache &cache) {
65
+ ModuleDependenciesCache &cache,
66
+ InterfaceSubContextDelegate &ASTDelegate) {
66
67
auto &ctx = instance.getASTContext ();
67
68
auto knownDependencies = *cache.findDependencies (module .first , module .second );
68
69
auto isSwift = knownDependencies.isSwiftModule ();
69
- auto ModuleCachePath = getModuleCachePathFromClang (ctx
70
- .getClangModuleLoader ()->getClangInstance ());
71
- auto &FEOpts = instance.getInvocation ().getFrontendOptions ();
72
- ModuleInterfaceLoaderOptions LoaderOpts (FEOpts);
73
- InterfaceSubContextDelegateImpl ASTDelegate (ctx.SourceMgr , ctx.Diags ,
74
- ctx.SearchPathOpts , ctx.LangOpts ,
75
- LoaderOpts,
76
- ctx.getClangModuleLoader (),
77
- /* buildModuleCacheDirIfAbsent*/ false ,
78
- ModuleCachePath,
79
- FEOpts.PrebuiltModuleCachePath ,
80
- FEOpts.SerializeModuleInterfaceDependencyHashes ,
81
- FEOpts.shouldTrackSystemDependencies ());
70
+
82
71
// Find the dependencies of every module this module directly depends on.
83
72
std::vector<ModuleDependencyID> result;
84
73
for (auto dependsOn : knownDependencies.getModuleDependencies ()) {
@@ -138,39 +127,75 @@ static std::vector<ModuleDependencyID> resolveDirectDependencies(
138
127
}
139
128
}
140
129
}
141
- // Only resolve cross-import overlays when this is the main module.
142
- // For other modules, these overlays are explicitly written.
143
- bool isMainModule =
144
- instance.getMainModule ()->getName ().str () == module .first &&
145
- module .second == ModuleDependenciesKind::Swift;
146
- if (isMainModule) {
147
- // Modules explicitly imported. Only these can be secondary module.
148
- std::vector<ModuleDependencyID> explicitImports = result;
149
- for (unsigned I = 0 ; I != result.size (); ++I) {
150
- auto dep = result[I];
151
- auto moduleName = dep.first ;
152
- auto dependencies = *cache.findDependencies (moduleName, dep.second );
153
- // Collect a map from secondary module name to cross-import overlay names.
154
- auto overlayMap = dependencies.collectCrossImportOverlayNames (
155
- instance.getASTContext (), moduleName);
156
- if (overlayMap.empty ())
157
- continue ;
158
- std::for_each (explicitImports.begin (), explicitImports.end (),
159
- [&](ModuleDependencyID Id) {
160
- // check if any explicitly imported modules can serve as a secondary
161
- // module, and add the overlay names to the dependencies list.
162
- for (auto overlayName: overlayMap[Id.first ]) {
163
- if (auto found = ctx.getModuleDependencies (overlayName.str (),
164
- /* onlyClangModule=*/ false ,
165
- cache,
166
- ASTDelegate)) {
167
- result.emplace_back (overlayName.str (), found->getKind ());
168
- }
130
+ return result;
131
+ }
132
+
133
+ static void discoverCrosssImportOverlayDependencies (
134
+ CompilerInstance &instance, StringRef mainModuleName,
135
+ ArrayRef<ModuleDependencyID> allDependencies,
136
+ ModuleDependenciesCache &cache, InterfaceSubContextDelegate &ASTDelegate,
137
+ llvm::function_ref<void (ModuleDependencyID)> action) {
138
+ // Modules explicitly imported. Only these can be secondary module.
139
+ llvm::SetVector<Identifier> newOverlays;
140
+ for (auto dep: allDependencies) {
141
+ auto moduleName = dep.first ;
142
+ auto dependencies = *cache.findDependencies (moduleName, dep.second );
143
+ // Collect a map from secondary module name to cross-import overlay names.
144
+ auto overlayMap = dependencies.collectCrossImportOverlayNames (
145
+ instance.getASTContext (), moduleName);
146
+ if (overlayMap.empty ())
147
+ continue ;
148
+ std::for_each (allDependencies.begin (), allDependencies.end (),
149
+ [&](ModuleDependencyID Id) {
150
+ // check if any explicitly imported modules can serve as a secondary
151
+ // module, and add the overlay names to the dependencies list.
152
+ for (auto overlayName: overlayMap[Id.first ]) {
153
+ if (std::find_if (allDependencies.begin (), allDependencies.end (),
154
+ [&](ModuleDependencyID Id) { return Id.first == overlayName.str (); })
155
+ == allDependencies.end ()) {
156
+ newOverlays.insert (overlayName);
169
157
}
170
- });
171
- }
158
+ }
159
+ });
172
160
}
173
- return result;
161
+ // No new cross-import overlays are found, return.
162
+ if (newOverlays.empty ())
163
+ return ;
164
+ // Construct a dummy main to resolve the newly discovered cross import overlays.
165
+ StringRef dummyMainName = " DummyMainModuleForResolvingCrossImportOverlays" ;
166
+ auto dummyMainDependencies = ModuleDependencies::forMainSwiftModule ({});
167
+
168
+ // Update main module's dependencies to include these new overlays.
169
+ auto mainDep = *cache.findDependencies (mainModuleName, ModuleDependenciesKind::Swift);
170
+ std::for_each (newOverlays.begin (), newOverlays.end (), [&](Identifier modName) {
171
+ dummyMainDependencies.addModuleDependency (modName.str ());
172
+ mainDep.addModuleDependency (modName.str ());
173
+ });
174
+ cache.updateDependencies ({mainModuleName, ModuleDependenciesKind::Swift}, mainDep);
175
+
176
+ // Record the dummy main module's direct dependencies. The dummy main module
177
+ // only directly depend on these newly discovered overlay modules.
178
+ cache.recordDependencies (dummyMainName, dummyMainDependencies,
179
+ ModuleDependenciesKind::Swift);
180
+ llvm::SetVector<ModuleDependencyID, std::vector<ModuleDependencyID>,
181
+ std::set<ModuleDependencyID>> allModules;
182
+
183
+ // Seed the all module list from the dummpy main module.
184
+ allModules.insert ({dummyMainName.str (), dummyMainDependencies.getKind ()});
185
+
186
+ // Explore the dependencies of every module.
187
+ for (unsigned currentModuleIdx = 0 ;
188
+ currentModuleIdx < allModules.size ();
189
+ ++currentModuleIdx) {
190
+ auto module = allModules[currentModuleIdx];
191
+ auto discoveredModules = resolveDirectDependencies (instance, module ,
192
+ cache, ASTDelegate);
193
+ allModules.insert (discoveredModules.begin (), discoveredModules.end ());
194
+ }
195
+ // Report any discovered modules to the clients, which include all overlays
196
+ // and their dependencies.
197
+ std::for_each (/* +1 to exclude dummy main*/ allModules.begin () + 1 ,
198
+ allModules.end (), action);
174
199
}
175
200
176
201
// / Write a single JSON field.
@@ -259,6 +284,7 @@ namespace {
259
284
static void writeJSON (llvm::raw_ostream &out,
260
285
CompilerInstance &instance,
261
286
ModuleDependenciesCache &cache,
287
+ InterfaceSubContextDelegate &ASTDelegate,
262
288
ArrayRef<ModuleDependencyID> allModules) {
263
289
// Write out a JSON description of all of the dependencies.
264
290
out << " {\n " ;
@@ -277,7 +303,8 @@ static void writeJSON(llvm::raw_ostream &out,
277
303
};
278
304
for (const auto &module : allModules) {
279
305
auto directDependencies = resolveDirectDependencies (
280
- instance, ModuleDependencyID (module .first , module .second ), cache);
306
+ instance, ModuleDependencyID (module .first , module .second ), cache,
307
+ ASTDelegate);
281
308
282
309
// Grab the completed module dependencies.
283
310
auto moduleDeps = *cache.findDependencies (module .first , module .second );
@@ -469,18 +496,18 @@ bool swift::scanDependencies(CompilerInstance &instance) {
469
496
break ;
470
497
471
498
case ImplicitStdlibKind::Stdlib:
472
- mainDependencies.addModuleDependency (" Swift" , alreadyAddedModules);
499
+ mainDependencies.addModuleDependency (" Swift" , & alreadyAddedModules);
473
500
break ;
474
501
}
475
502
476
503
// Add any implicit module names.
477
504
for (const auto &moduleName : importInfo.ModuleNames ) {
478
- mainDependencies.addModuleDependency (moduleName.str (), alreadyAddedModules);
505
+ mainDependencies.addModuleDependency (moduleName.str (), & alreadyAddedModules);
479
506
}
480
507
481
508
// Already-loaded, implicitly imported module names.
482
509
for (const auto &module : importInfo.AdditionalModules ) {
483
- mainDependencies.addModuleDependency (module .first ->getNameStr (), alreadyAddedModules);
510
+ mainDependencies.addModuleDependency (module .first ->getNameStr (), & alreadyAddedModules);
484
511
}
485
512
486
513
// Add the bridging header.
@@ -492,7 +519,7 @@ bool swift::scanDependencies(CompilerInstance &instance) {
492
519
// add a dependency with the same name to trigger the search.
493
520
if (importInfo.ShouldImportUnderlyingModule ) {
494
521
mainDependencies.addModuleDependency (mainModule->getName ().str (),
495
- alreadyAddedModules);
522
+ & alreadyAddedModules);
496
523
}
497
524
}
498
525
@@ -508,18 +535,40 @@ bool swift::scanDependencies(CompilerInstance &instance) {
508
535
cache.recordDependencies (mainModuleName, std::move (mainDependencies),
509
536
ModuleDependenciesKind::Swift);
510
537
538
+ auto &ctx = instance.getASTContext ();
539
+ auto ModuleCachePath = getModuleCachePathFromClang (ctx
540
+ .getClangModuleLoader ()->getClangInstance ());
541
+ auto &FEOpts = instance.getInvocation ().getFrontendOptions ();
542
+ ModuleInterfaceLoaderOptions LoaderOpts (FEOpts);
543
+ InterfaceSubContextDelegateImpl ASTDelegate (ctx.SourceMgr , ctx.Diags ,
544
+ ctx.SearchPathOpts , ctx.LangOpts ,
545
+ LoaderOpts,
546
+ ctx.getClangModuleLoader (),
547
+ /* buildModuleCacheDirIfAbsent*/ false ,
548
+ ModuleCachePath,
549
+ FEOpts.PrebuiltModuleCachePath ,
550
+ FEOpts.SerializeModuleInterfaceDependencyHashes ,
551
+ FEOpts.shouldTrackSystemDependencies ());
552
+
511
553
// Explore the dependencies of every module.
512
554
for (unsigned currentModuleIdx = 0 ;
513
555
currentModuleIdx < allModules.size ();
514
556
++currentModuleIdx) {
515
557
auto module = allModules[currentModuleIdx];
516
558
auto discoveredModules =
517
- resolveDirectDependencies (instance, module , cache);
559
+ resolveDirectDependencies (instance, module , cache, ASTDelegate );
518
560
allModules.insert (discoveredModules.begin (), discoveredModules.end ());
519
561
}
520
562
563
+ // We have all explicit imports now, resolve cross import overlays.
564
+ discoverCrosssImportOverlayDependencies (instance, mainModuleName,
565
+ /* All transitive dependencies*/ allModules.getArrayRef ().slice (1 ), cache,
566
+ ASTDelegate, [&](ModuleDependencyID id) {
567
+ allModules.insert (id);
568
+ });
569
+
521
570
// Write out the JSON description.
522
- writeJSON (out, instance, cache, allModules.getArrayRef ());
571
+ writeJSON (out, instance, cache, ASTDelegate, allModules.getArrayRef ());
523
572
524
573
// Update the dependency tracker.
525
574
if (auto depTracker = instance.getDependencyTracker ()) {
0 commit comments