@@ -163,8 +163,6 @@ namespace {
163
163
164
164
std::set<const FileEntry *> GetAffectingModuleMaps (const Preprocessor &PP,
165
165
Module *RootModule) {
166
- std::set<const FileEntry *> ModuleMaps{};
167
- std::set<const Module *> ProcessedModules;
168
166
SmallVector<const Module *> ModulesToProcess{RootModule};
169
167
170
168
const HeaderSearch &HS = PP.getHeaderSearchInfo ();
@@ -195,42 +193,45 @@ std::set<const FileEntry *> GetAffectingModuleMaps(const Preprocessor &PP,
195
193
const ModuleMap &MM = HS.getModuleMap ();
196
194
SourceManager &SourceMgr = PP.getSourceManager ();
197
195
198
- auto ForIncludeChain = [&](FileEntryRef F,
199
- llvm::function_ref<void (FileEntryRef)> CB) {
200
- CB (F);
196
+ std::set<const FileEntry *> ModuleMaps{};
197
+ auto CollectIncludingModuleMaps = [&](FileEntryRef F) {
198
+ if (!ModuleMaps.insert (F).second )
199
+ return ;
201
200
FileID FID = SourceMgr.translateFile (F);
202
201
SourceLocation Loc = SourceMgr.getIncludeLoc (FID);
203
202
// The include location of inferred module maps can point into the header
204
203
// file that triggered the inferring. Cut off the walk if that's the case.
205
204
while (Loc.isValid () && isModuleMap (SourceMgr.getFileCharacteristic (Loc))) {
206
205
FID = SourceMgr.getFileID (Loc);
207
- CB (*SourceMgr.getFileEntryRefForID (FID));
206
+ if (!ModuleMaps.insert (*SourceMgr.getFileEntryRefForID (FID)).second )
207
+ break ;
208
208
Loc = SourceMgr.getIncludeLoc (FID);
209
209
}
210
210
};
211
211
212
- auto ProcessModuleOnce = [&](const Module *M) {
213
- for (const Module *Mod = M; Mod; Mod = Mod->Parent )
214
- if (ProcessedModules.insert (Mod).second ) {
215
- auto Insert = [&](FileEntryRef F) { ModuleMaps.insert (F); };
216
- // The containing module map is affecting, because it's being pointed
217
- // into by Module::DefinitionLoc.
218
- if (auto ModuleMapFile = MM.getContainingModuleMapFile (Mod))
219
- ForIncludeChain (*ModuleMapFile, Insert);
220
- // For inferred modules, the module map that allowed inferring is not in
221
- // the include chain of the virtual containing module map file. It did
222
- // affect the compilation, though.
223
- if (auto ModuleMapFile = MM.getModuleMapFileForUniquing (Mod))
224
- ForIncludeChain (*ModuleMapFile, Insert);
225
- }
212
+ std::set<const Module *> ProcessedModules;
213
+ auto CollectIncludingMapsFromAncestors = [&](const Module *M) {
214
+ for (const Module *Mod = M; Mod; Mod = Mod->Parent ) {
215
+ if (!ProcessedModules.insert (Mod).second )
216
+ break ;
217
+ // The containing module map is affecting, because it's being pointed
218
+ // into by Module::DefinitionLoc.
219
+ if (auto ModuleMapFile = MM.getContainingModuleMapFile (Mod))
220
+ CollectIncludingModuleMaps (*ModuleMapFile);
221
+ // For inferred modules, the module map that allowed inferring is not in
222
+ // the include chain of the virtual containing module map file. It did
223
+ // affect the compilation, though.
224
+ if (auto ModuleMapFile = MM.getModuleMapFileForUniquing (Mod))
225
+ CollectIncludingModuleMaps (*ModuleMapFile);
226
+ }
226
227
};
227
228
228
229
for (const Module *CurrentModule : ModulesToProcess) {
229
- ProcessModuleOnce (CurrentModule);
230
+ CollectIncludingMapsFromAncestors (CurrentModule);
230
231
for (const Module *ImportedModule : CurrentModule->Imports )
231
- ProcessModuleOnce (ImportedModule);
232
+ CollectIncludingMapsFromAncestors (ImportedModule);
232
233
for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses )
233
- ProcessModuleOnce (UndeclaredModule);
234
+ CollectIncludingMapsFromAncestors (UndeclaredModule);
234
235
}
235
236
236
237
return ModuleMaps;
0 commit comments