@@ -184,14 +184,30 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
184184 const SourceManager &SM = PP.getSourceManager ();
185185 const ModuleMap &MM = HS.getModuleMap ();
186186
187- llvm::DenseSet<FileID> ModuleMaps;
188-
189- llvm::DenseSet<const Module *> ProcessedModules;
190- auto CollectModuleMapsForHierarchy = [&](const Module *M) {
187+ // Module maps used only by textual headers are special. Their FileID is
188+ // non-affecting, but their FileEntry is (i.e. must be written as InputFile).
189+ enum AffectedReason : bool {
190+ AR_TextualHeader = 0 ,
191+ AR_ImportOrTextualHeader = 1 ,
192+ };
193+ auto AssignMostImportant = [](AffectedReason &LHS, AffectedReason RHS) {
194+ LHS = std::max (LHS, RHS);
195+ };
196+ llvm::DenseMap<FileID, AffectedReason> ModuleMaps;
197+ llvm::DenseMap<const Module *, AffectedReason> ProcessedModules;
198+ auto CollectModuleMapsForHierarchy = [&](const Module *M,
199+ AffectedReason Reason) {
191200 M = M->getTopLevelModule ();
192201
193- if (!ProcessedModules.insert (M).second )
202+ // We need to process the header either when it was not present or when we
203+ // previously flagged module map as textual headers and now we found a
204+ // proper import.
205+ if (auto [It, Inserted] = ProcessedModules.insert ({M, Reason});
206+ !Inserted && Reason <= It->second ) {
194207 return ;
208+ } else {
209+ It->second = Reason;
210+ }
195211
196212 std::queue<const Module *> Q;
197213 Q.push (M);
@@ -202,12 +218,12 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
202218 // The containing module map is affecting, because it's being pointed
203219 // into by Module::DefinitionLoc.
204220 if (auto F = MM.getContainingModuleMapFileID (Mod); F.isValid ())
205- ModuleMaps. insert (F );
221+ AssignMostImportant (ModuleMaps[F], Reason );
206222 // For inferred modules, the module map that allowed inferring is not
207223 // related to the virtual containing module map file. It did affect the
208224 // compilation, though.
209225 if (auto UniqF = MM.getModuleMapFileIDForUniquing (Mod); UniqF.isValid ())
210- ModuleMaps. insert ( UniqF);
226+ AssignMostImportant (ModuleMaps[ UniqF], Reason );
211227
212228 for (auto *SubM : Mod->submodules ())
213229 Q.push (SubM);
@@ -216,7 +232,7 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
216232
217233 // Handle all the affecting modules referenced from the root module.
218234
219- CollectModuleMapsForHierarchy (RootModule);
235+ CollectModuleMapsForHierarchy (RootModule, AR_ImportOrTextualHeader );
220236
221237 std::queue<const Module *> Q;
222238 Q.push (RootModule);
@@ -225,9 +241,9 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
225241 Q.pop ();
226242
227243 for (const Module *ImportedModule : CurrentModule->Imports )
228- CollectModuleMapsForHierarchy (ImportedModule);
244+ CollectModuleMapsForHierarchy (ImportedModule, AR_ImportOrTextualHeader );
229245 for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses )
230- CollectModuleMapsForHierarchy (UndeclaredModule);
246+ CollectModuleMapsForHierarchy (UndeclaredModule, AR_ImportOrTextualHeader );
231247
232248 for (auto *M : CurrentModule->submodules ())
233249 Q.push (M);
@@ -256,7 +272,7 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
256272
257273 for (const auto &KH : HS.findResolvedModulesForHeader (*File))
258274 if (const Module *M = KH.getModule ())
259- CollectModuleMapsForHierarchy (M);
275+ CollectModuleMapsForHierarchy (M, AR_TextualHeader );
260276 }
261277
262278 // FIXME: This algorithm is not correct for module map hierarchies where
@@ -278,13 +294,16 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
278294 // includes a module map defining a module that's not a submodule of X.
279295
280296 llvm::DenseSet<const FileEntry *> ModuleFileEntries;
281- for (FileID MM : ModuleMaps) {
282- if (auto *FE = SM.getFileEntryForID (MM))
297+ llvm::DenseSet<FileID> ModuleFileIDs;
298+ for (auto [FID, Reason] : ModuleMaps) {
299+ if (Reason == AR_ImportOrTextualHeader)
300+ ModuleFileIDs.insert (FID);
301+ if (auto *FE = SM.getFileEntryForID (FID))
283302 ModuleFileEntries.insert (FE);
284303 }
285304
286305 AffectingModuleMaps R;
287- R.DefinitionFileIDs = std::move (ModuleMaps );
306+ R.DefinitionFileIDs = std::move (ModuleFileIDs );
288307 R.DefinitionFiles = std::move (ModuleFileEntries);
289308 return std::move (R);
290309}
0 commit comments