@@ -59,8 +59,8 @@ ModuleFile *ModuleManager::lookupByModuleName(StringRef Name) const {
59
59
return nullptr ;
60
60
}
61
61
62
- ModuleFile *ModuleManager::lookup (const FileEntry * File) const {
63
- return Modules.lookup (File);
62
+ ModuleFile *ModuleManager::lookup (FileEntryRef File) const {
63
+ return Modules.lookup (File. getName () );
64
64
}
65
65
66
66
std::unique_ptr<llvm::MemoryBuffer>
@@ -107,120 +107,92 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
107
107
std::string &ErrorStr) {
108
108
Module = nullptr ;
109
109
110
- // Look for the file entry. This only fails if the expected size or
111
- // modification time differ.
112
- OptionalFileEntryRef Entry;
113
- if (Type == MK_ExplicitModule || Type == MK_PrebuiltModule) {
114
- // If we're not expecting to pull this file out of the module cache, it
115
- // might have a different mtime due to being moved across filesystems in
116
- // a distributed build. The size must still match, though. (As must the
117
- // contents, but we can't check that.)
118
- ExpectedModTime = 0 ;
119
- }
120
- // Note: ExpectedSize and ExpectedModTime will be 0 for MK_ImplicitModule
121
- // when using an ASTFileSignature.
122
- if (lookupModuleFile (FileName, ExpectedSize, ExpectedModTime, Entry)) {
123
- ErrorStr = " module file has a different size or mtime than expected" ;
124
- return OutOfDate;
125
- }
126
-
127
- if (!Entry) {
128
- ErrorStr = " module file not found" ;
129
- return Missing;
130
- }
131
-
132
- // The ModuleManager's use of FileEntry nodes as the keys for its map of
133
- // loaded modules is less than ideal. Uniqueness for FileEntry nodes is
134
- // maintained by FileManager, which in turn uses inode numbers on hosts
135
- // that support that. When coupled with the module cache's proclivity for
136
- // turning over and deleting stale PCMs, this means entries for different
137
- // module files can wind up reusing the same underlying inode. When this
138
- // happens, subsequent accesses to the Modules map will disagree on the
139
- // ModuleFile associated with a given file. In general, it is not sufficient
140
- // to resolve this conundrum with a type like FileEntryRef that stores the
141
- // name of the FileEntry node on first access because of path canonicalization
142
- // issues. However, the paths constructed for implicit module builds are
143
- // fully under Clang's control. We *can*, therefore, rely on their structure
144
- // being consistent across operating systems and across subsequent accesses
145
- // to the Modules map.
146
- auto implicitModuleNamesMatch = [](ModuleKind Kind, const ModuleFile *MF,
147
- FileEntryRef Entry) -> bool {
148
- if (Kind != MK_ImplicitModule)
149
- return true ;
150
- return Entry.getName () == MF->FileName ;
151
- };
152
-
153
110
// Check whether we already loaded this module, before
154
- if (ModuleFile *ModuleEntry = Modules.lookup (*Entry)) {
155
- if (implicitModuleNamesMatch (Type, ModuleEntry, *Entry)) {
156
- // Check the stored signature.
157
- if (checkSignature (ModuleEntry->Signature , ExpectedSignature, ErrorStr))
158
- return OutOfDate;
159
-
160
- Module = ModuleEntry;
161
- updateModuleImports (*ModuleEntry, ImportedBy, ImportLoc);
162
- return AlreadyLoaded;
163
- }
111
+ if (ModuleFile *ModuleEntry = Modules.lookup (FileName)) {
112
+ // Check the stored signature.
113
+ if (checkSignature (ModuleEntry->Signature , ExpectedSignature, ErrorStr))
114
+ return OutOfDate;
115
+
116
+ Module = ModuleEntry;
117
+ updateModuleImports (*ModuleEntry, ImportedBy, ImportLoc);
118
+ return AlreadyLoaded;
164
119
}
165
120
166
- // Allocate a new module.
167
- auto NewModule = std::make_unique<ModuleFile>(Type, *Entry, Generation);
168
- NewModule->Index = Chain.size ();
169
- NewModule->FileName = FileName.str ();
170
- NewModule->ImportLoc = ImportLoc;
171
- NewModule->InputFilesValidationTimestamp = 0 ;
172
-
173
- if (NewModule->Kind == MK_ImplicitModule) {
174
- std::string TimestampFilename =
175
- ModuleFile::getTimestampFilename (NewModule->FileName );
176
- llvm::vfs::Status Status;
177
- // A cached stat value would be fine as well.
178
- if (!FileMgr.getNoncachedStatValue (TimestampFilename, Status))
179
- NewModule->InputFilesValidationTimestamp =
180
- llvm::sys::toTimeT (Status.getLastModificationTime ());
181
- }
121
+ OptionalFileEntryRef Entry;
122
+ llvm::MemoryBuffer *ModuleBuffer = nullptr ;
182
123
183
124
// Load the contents of the module
184
125
if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer (FileName)) {
185
126
// The buffer was already provided for us.
186
- NewModule-> Buffer = &getModuleCache ().getInMemoryModuleCache ().addBuiltPCM (
127
+ ModuleBuffer = &getModuleCache ().getInMemoryModuleCache ().addBuiltPCM (
187
128
FileName, std::move (Buffer));
188
- // Since the cached buffer is reused, it is safe to close the file
189
- // descriptor that was opened while stat()ing the PCM in
190
- // lookupModuleFile() above, it won't be needed any longer.
191
- Entry->closeFile ();
192
129
} else if (llvm::MemoryBuffer *Buffer =
193
130
getModuleCache ().getInMemoryModuleCache ().lookupPCM (
194
131
FileName)) {
195
- NewModule->Buffer = Buffer;
196
- // As above, the file descriptor is no longer needed.
197
- Entry->closeFile ();
132
+ ModuleBuffer = Buffer;
198
133
} else if (getModuleCache ().getInMemoryModuleCache ().shouldBuildPCM (
199
134
FileName)) {
200
135
// Report that the module is out of date, since we tried (and failed) to
201
136
// import it earlier.
202
- Entry->closeFile ();
203
137
return OutOfDate;
204
138
} else {
139
+ Entry = FileName == " -"
140
+ ? expectedToOptional (FileMgr.getSTDIN ())
141
+ : FileMgr.getOptionalFileRef (FileName, /* OpenFile=*/ true ,
142
+ /* CacheFailure=*/ false );
143
+ if (!Entry) {
144
+ ErrorStr = " module file not found" ;
145
+ return Missing;
146
+ }
147
+
205
148
// Get a buffer of the file and close the file descriptor when done.
206
149
// The file is volatile because in a parallel build we expect multiple
207
150
// compiler processes to use the same module file rebuilding it if needed.
208
151
//
209
152
// RequiresNullTerminator is false because module files don't need it, and
210
153
// this allows the file to still be mmapped.
211
- auto Buf = FileMgr.getBufferForFile (NewModule->File ,
212
- /* IsVolatile=*/ true ,
154
+ auto Buf = FileMgr.getBufferForFile (*Entry, /* IsVolatile=*/ true ,
213
155
/* RequiresNullTerminator=*/ false );
214
156
215
157
if (!Buf) {
216
158
ErrorStr = Buf.getError ().message ();
217
159
return Missing;
218
160
}
219
161
220
- NewModule->Buffer = &getModuleCache ().getInMemoryModuleCache ().addPCM (
162
+ if ((ExpectedSize && ExpectedSize != Entry->getSize ()) ||
163
+ (ExpectedModTime && ExpectedModTime != Entry->getModificationTime ())) {
164
+ ErrorStr = " module file has a different size or mtime than expected" ;
165
+ return OutOfDate;
166
+ }
167
+
168
+ ModuleBuffer = &getModuleCache ().getInMemoryModuleCache ().addPCM (
221
169
FileName, std::move (*Buf));
222
170
}
223
171
172
+ // TODO: Make it so that ModuleFile is not tied to a FileEntry.
173
+ if (!Entry && !((Entry = FileMgr.getVirtualFileRef (FileName, ExpectedSize,
174
+ ExpectedModTime))))
175
+ return Missing;
176
+
177
+ // Allocate a new module.
178
+ auto NewModule = std::make_unique<ModuleFile>(Type, *Entry, Generation);
179
+ NewModule->Index = Chain.size ();
180
+ NewModule->FileName = FileName.str ();
181
+ NewModule->ImportLoc = ImportLoc;
182
+ NewModule->InputFilesValidationTimestamp = 0 ;
183
+
184
+ if (NewModule->Kind == MK_ImplicitModule) {
185
+ std::string TimestampFilename =
186
+ ModuleFile::getTimestampFilename (NewModule->FileName );
187
+ llvm::vfs::Status Status;
188
+ // A cached stat value would be fine as well.
189
+ if (!FileMgr.getNoncachedStatValue (TimestampFilename, Status))
190
+ NewModule->InputFilesValidationTimestamp =
191
+ llvm::sys::toTimeT (Status.getLastModificationTime ());
192
+ }
193
+
194
+ NewModule->Buffer = ModuleBuffer;
195
+
224
196
// Initialize the stream.
225
197
NewModule->Data = PCHContainerRdr.ExtractPCH (*NewModule->Buffer );
226
198
@@ -231,7 +203,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
231
203
return OutOfDate;
232
204
233
205
// We're keeping this module. Store it everywhere.
234
- Module = Modules[*Entry ] = NewModule.get ();
206
+ Module = Modules[FileName ] = NewModule.get ();
235
207
236
208
updateModuleImports (*NewModule, ImportedBy, ImportLoc);
237
209
@@ -277,7 +249,7 @@ void ModuleManager::removeModules(ModuleIterator First) {
277
249
278
250
// Delete the modules.
279
251
for (ModuleIterator victim = First; victim != Last; ++victim)
280
- Modules.erase (victim->File );
252
+ Modules.erase (victim->File . getName () );
281
253
282
254
Chain.erase (Chain.begin () + (First - begin ()), Chain.end ());
283
255
}
@@ -436,29 +408,6 @@ void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
436
408
returnVisitState (std::move (State));
437
409
}
438
410
439
- bool ModuleManager::lookupModuleFile (StringRef FileName, off_t ExpectedSize,
440
- time_t ExpectedModTime,
441
- OptionalFileEntryRef &File) {
442
- if (FileName == " -" ) {
443
- File = expectedToOptional (FileMgr.getSTDIN ());
444
- return false ;
445
- }
446
-
447
- // Open the file immediately to ensure there is no race between stat'ing and
448
- // opening the file.
449
- File = FileMgr.getOptionalFileRef (FileName, /* OpenFile=*/ true ,
450
- /* CacheFailure=*/ false );
451
-
452
- if (File &&
453
- ((ExpectedSize && ExpectedSize != File->getSize ()) ||
454
- (ExpectedModTime && ExpectedModTime != File->getModificationTime ())))
455
- // Do not destroy File, as it may be referenced. If we need to rebuild it,
456
- // it will be destroyed by removeModules.
457
- return true ;
458
-
459
- return false ;
460
- }
461
-
462
411
#ifndef NDEBUG
463
412
namespace llvm {
464
413
0 commit comments