@@ -184,14 +184,30 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
184
184
const SourceManager &SM = PP.getSourceManager ();
185
185
const ModuleMap &MM = HS.getModuleMap ();
186
186
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) {
191
200
M = M->getTopLevelModule ();
192
201
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 ) {
194
207
return ;
208
+ } else {
209
+ It->second = Reason;
210
+ }
195
211
196
212
std::queue<const Module *> Q;
197
213
Q.push (M);
@@ -202,12 +218,12 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
202
218
// The containing module map is affecting, because it's being pointed
203
219
// into by Module::DefinitionLoc.
204
220
if (auto F = MM.getContainingModuleMapFileID (Mod); F.isValid ())
205
- ModuleMaps. insert (F );
221
+ AssignMostImportant (ModuleMaps[F], Reason );
206
222
// For inferred modules, the module map that allowed inferring is not
207
223
// related to the virtual containing module map file. It did affect the
208
224
// compilation, though.
209
225
if (auto UniqF = MM.getModuleMapFileIDForUniquing (Mod); UniqF.isValid ())
210
- ModuleMaps. insert ( UniqF);
226
+ AssignMostImportant (ModuleMaps[ UniqF], Reason );
211
227
212
228
for (auto *SubM : Mod->submodules ())
213
229
Q.push (SubM);
@@ -216,7 +232,7 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
216
232
217
233
// Handle all the affecting modules referenced from the root module.
218
234
219
- CollectModuleMapsForHierarchy (RootModule);
235
+ CollectModuleMapsForHierarchy (RootModule, AR_ImportOrTextualHeader );
220
236
221
237
std::queue<const Module *> Q;
222
238
Q.push (RootModule);
@@ -225,9 +241,9 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
225
241
Q.pop ();
226
242
227
243
for (const Module *ImportedModule : CurrentModule->Imports )
228
- CollectModuleMapsForHierarchy (ImportedModule);
244
+ CollectModuleMapsForHierarchy (ImportedModule, AR_ImportOrTextualHeader );
229
245
for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses )
230
- CollectModuleMapsForHierarchy (UndeclaredModule);
246
+ CollectModuleMapsForHierarchy (UndeclaredModule, AR_ImportOrTextualHeader );
231
247
232
248
for (auto *M : CurrentModule->submodules ())
233
249
Q.push (M);
@@ -256,7 +272,7 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
256
272
257
273
for (const auto &KH : HS.findResolvedModulesForHeader (*File))
258
274
if (const Module *M = KH.getModule ())
259
- CollectModuleMapsForHierarchy (M);
275
+ CollectModuleMapsForHierarchy (M, AR_TextualHeader );
260
276
}
261
277
262
278
// FIXME: This algorithm is not correct for module map hierarchies where
@@ -278,13 +294,16 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
278
294
// includes a module map defining a module that's not a submodule of X.
279
295
280
296
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))
283
302
ModuleFileEntries.insert (FE);
284
303
}
285
304
286
305
AffectingModuleMaps R;
287
- R.DefinitionFileIDs = std::move (ModuleMaps );
306
+ R.DefinitionFileIDs = std::move (ModuleFileIDs );
288
307
R.DefinitionFiles = std::move (ModuleFileEntries);
289
308
return std::move (R);
290
309
}
0 commit comments