@@ -59,7 +59,7 @@ ModuleFile *ModuleManager::lookupByModuleName(StringRef Name) const {
59
59
}
60
60
61
61
ModuleFile *ModuleManager::lookup (const FileEntry *File) const {
62
- auto Known = Modules.find (EntryKey{ File} );
62
+ auto Known = Modules.find (File);
63
63
if (Known == Modules.end ())
64
64
return nullptr ;
65
65
@@ -72,7 +72,7 @@ ModuleManager::lookupBuffer(StringRef Name) {
72
72
/* CacheFailure=*/ false );
73
73
if (!Entry)
74
74
return nullptr ;
75
- return std::move (InMemoryBuffers[EntryKey{ *Entry} ]);
75
+ return std::move (InMemoryBuffers[*Entry]);
76
76
}
77
77
78
78
static bool checkSignature (ASTFileSignature Signature,
@@ -132,15 +132,38 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
132
132
return Missing;
133
133
}
134
134
135
+ // The ModuleManager's use of FileEntry nodes as the keys for its map of
136
+ // loaded modules is less than ideal. Uniqueness for FileEntry nodes is
137
+ // maintained by FileManager, which in turn uses inode numbers on hosts
138
+ // that support that. When coupled with the module cache's proclivity for
139
+ // turning over and deleting stale PCMs, this means entries for different
140
+ // module files can wind up reusing the same underlying inode. When this
141
+ // happens, subsequent accesses to the Modules map will disagree on the
142
+ // ModuleFile associated with a given file. In general, it is not sufficient
143
+ // to resolve this conundrum with a type like FileEntryRef that stores the
144
+ // name of the FileEntry node on first access because of path canonicalization
145
+ // issues. However, the paths constructed for implicit module builds are
146
+ // fully under Clang's control. We *can*, therefore, rely on their structure
147
+ // being consistent across operating systems and across subsequent accesses
148
+ // to the Modules map.
149
+ auto implicitModuleNamesMatch = [](ModuleKind Kind, const ModuleFile *MF,
150
+ const FileEntry *Entry) -> bool {
151
+ if (Kind != MK_ImplicitModule)
152
+ return true ;
153
+ return Entry->getName () == MF->FileName ;
154
+ };
155
+
135
156
// Check whether we already loaded this module, before
136
- if (ModuleFile *ModuleEntry = Modules.lookup (EntryKey{Entry})) {
137
- // Check the stored signature.
138
- if (checkSignature (ModuleEntry->Signature , ExpectedSignature, ErrorStr))
139
- return OutOfDate;
140
-
141
- Module = ModuleEntry;
142
- updateModuleImports (*ModuleEntry, ImportedBy, ImportLoc);
143
- return AlreadyLoaded;
157
+ if (ModuleFile *ModuleEntry = Modules.lookup (Entry)) {
158
+ if (implicitModuleNamesMatch (Type, ModuleEntry, Entry)) {
159
+ // Check the stored signature.
160
+ if (checkSignature (ModuleEntry->Signature , ExpectedSignature, ErrorStr))
161
+ return OutOfDate;
162
+
163
+ Module = ModuleEntry;
164
+ updateModuleImports (*ModuleEntry, ImportedBy, ImportLoc);
165
+ return AlreadyLoaded;
166
+ }
144
167
}
145
168
146
169
// Allocate a new module.
@@ -208,7 +231,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
208
231
return OutOfDate;
209
232
210
233
// We're keeping this module. Store it everywhere.
211
- Module = Modules[EntryKey{ Entry} ] = NewModule.get ();
234
+ Module = Modules[Entry] = NewModule.get ();
212
235
213
236
updateModuleImports (*NewModule, ImportedBy, ImportLoc);
214
237
@@ -255,7 +278,7 @@ void ModuleManager::removeModules(ModuleIterator First, ModuleMap *modMap) {
255
278
256
279
// Delete the modules and erase them from the various structures.
257
280
for (ModuleIterator victim = First; victim != Last; ++victim) {
258
- Modules.erase (EntryKey{ victim->File } );
281
+ Modules.erase (victim->File );
259
282
260
283
if (modMap) {
261
284
StringRef ModuleName = victim->ModuleName ;
@@ -274,7 +297,7 @@ ModuleManager::addInMemoryBuffer(StringRef FileName,
274
297
std::unique_ptr<llvm::MemoryBuffer> Buffer) {
275
298
const FileEntry *Entry =
276
299
FileMgr.getVirtualFile (FileName, Buffer->getBufferSize (), 0 );
277
- InMemoryBuffers[EntryKey{ Entry} ] = std::move (Buffer);
300
+ InMemoryBuffers[Entry] = std::move (Buffer);
278
301
}
279
302
280
303
ModuleManager::VisitState *ModuleManager::allocateVisitState () {
0 commit comments