1 //===- ModuleManager.cpp - Module Manager ---------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines the ModuleManager class, which manages a set of loaded
10 // modules for the ASTReader.
12 //===----------------------------------------------------------------------===//
14 #include "clang/Serialization/ModuleManager.h"
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Basic/LLVM.h"
17 #include "clang/Lex/HeaderSearch.h"
18 #include "clang/Lex/ModuleMap.h"
19 #include "clang/Serialization/GlobalModuleIndex.h"
20 #include "clang/Serialization/InMemoryModuleCache.h"
21 #include "clang/Serialization/ModuleFile.h"
22 #include "clang/Serialization/PCHContainerOperations.h"
23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/SetVector.h"
25 #include "llvm/ADT/SmallPtrSet.h"
26 #include "llvm/ADT/SmallVector.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/ADT/iterator.h"
29 #include "llvm/Support/Chrono.h"
30 #include "llvm/Support/DOTGraphTraits.h"
31 #include "llvm/Support/ErrorOr.h"
32 #include "llvm/Support/GraphWriter.h"
33 #include "llvm/Support/MemoryBuffer.h"
34 #include "llvm/Support/VirtualFileSystem.h"
39 #include <system_error>
41 using namespace clang
;
42 using namespace serialization
;
44 ModuleFile
*ModuleManager::lookupByFileName(StringRef Name
) const {
45 auto Entry
= FileMgr
.getFile(Name
, /*OpenFile=*/false,
46 /*CacheFailure=*/false);
48 return lookup(*Entry
);
53 ModuleFile
*ModuleManager::lookupByModuleName(StringRef Name
) const {
54 if (const Module
*Mod
= HeaderSearchInfo
.getModuleMap().findModule(Name
))
55 if (const FileEntry
*File
= Mod
->getASTFile())
61 ModuleFile
*ModuleManager::lookup(const FileEntry
*File
) const {
62 auto Known
= Modules
.find(File
);
63 if (Known
== Modules
.end())
69 std::unique_ptr
<llvm::MemoryBuffer
>
70 ModuleManager::lookupBuffer(StringRef Name
) {
71 auto Entry
= FileMgr
.getFile(Name
, /*OpenFile=*/false,
72 /*CacheFailure=*/false);
75 return std::move(InMemoryBuffers
[*Entry
]);
78 static bool checkSignature(ASTFileSignature Signature
,
79 ASTFileSignature ExpectedSignature
,
80 std::string
&ErrorStr
) {
81 if (!ExpectedSignature
|| Signature
== ExpectedSignature
)
85 Signature
? "signature mismatch" : "could not read module signature";
89 static void updateModuleImports(ModuleFile
&MF
, ModuleFile
*ImportedBy
,
90 SourceLocation ImportLoc
) {
92 MF
.ImportedBy
.insert(ImportedBy
);
93 ImportedBy
->Imports
.insert(&MF
);
95 if (!MF
.DirectlyImported
)
96 MF
.ImportLoc
= ImportLoc
;
98 MF
.DirectlyImported
= true;
102 ModuleManager::AddModuleResult
103 ModuleManager::addModule(StringRef FileName
, ModuleKind Type
,
104 SourceLocation ImportLoc
, ModuleFile
*ImportedBy
,
106 off_t ExpectedSize
, time_t ExpectedModTime
,
107 ASTFileSignature ExpectedSignature
,
108 ASTFileSignatureReader ReadSignature
,
110 std::string
&ErrorStr
) {
113 // Look for the file entry. This only fails if the expected size or
114 // modification time differ.
115 OptionalFileEntryRefDegradesToFileEntryPtr Entry
;
116 if (Type
== MK_ExplicitModule
|| Type
== MK_PrebuiltModule
) {
117 // If we're not expecting to pull this file out of the module cache, it
118 // might have a different mtime due to being moved across filesystems in
119 // a distributed build. The size must still match, though. (As must the
120 // contents, but we can't check that.)
123 // Note: ExpectedSize and ExpectedModTime will be 0 for MK_ImplicitModule
124 // when using an ASTFileSignature.
125 if (lookupModuleFile(FileName
, ExpectedSize
, ExpectedModTime
, Entry
)) {
126 ErrorStr
= "module file out of date";
130 if (!Entry
&& FileName
!= "-") {
131 ErrorStr
= "module file not found";
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
)
153 return Entry
->getName() == MF
->FileName
;
156 // Check whether we already loaded this module, before
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
))
163 Module
= ModuleEntry
;
164 updateModuleImports(*ModuleEntry
, ImportedBy
, ImportLoc
);
165 return AlreadyLoaded
;
169 // Allocate a new module.
170 auto NewModule
= std::make_unique
<ModuleFile
>(Type
, Generation
);
171 NewModule
->Index
= Chain
.size();
172 NewModule
->FileName
= FileName
.str();
173 NewModule
->File
= Entry
;
174 NewModule
->ImportLoc
= ImportLoc
;
175 NewModule
->InputFilesValidationTimestamp
= 0;
177 if (NewModule
->Kind
== MK_ImplicitModule
) {
178 std::string TimestampFilename
= NewModule
->getTimestampFilename();
179 llvm::vfs::Status Status
;
180 // A cached stat value would be fine as well.
181 if (!FileMgr
.getNoncachedStatValue(TimestampFilename
, Status
))
182 NewModule
->InputFilesValidationTimestamp
=
183 llvm::sys::toTimeT(Status
.getLastModificationTime());
186 // Load the contents of the module
187 if (std::unique_ptr
<llvm::MemoryBuffer
> Buffer
= lookupBuffer(FileName
)) {
188 // The buffer was already provided for us.
189 NewModule
->Buffer
= &ModuleCache
->addBuiltPCM(FileName
, std::move(Buffer
));
190 // Since the cached buffer is reused, it is safe to close the file
191 // descriptor that was opened while stat()ing the PCM in
192 // lookupModuleFile() above, it won't be needed any longer.
194 } else if (llvm::MemoryBuffer
*Buffer
=
195 getModuleCache().lookupPCM(FileName
)) {
196 NewModule
->Buffer
= Buffer
;
197 // As above, the file descriptor is no longer needed.
199 } else if (getModuleCache().shouldBuildPCM(FileName
)) {
200 // Report that the module is out of date, since we tried (and failed) to
201 // import it earlier.
205 // Open the AST file.
206 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>> Buf((std::error_code()));
207 if (FileName
== "-") {
208 Buf
= llvm::MemoryBuffer::getSTDIN();
210 // Get a buffer of the file and close the file descriptor when done.
211 // The file is volatile because in a parallel build we expect multiple
212 // compiler processes to use the same module file rebuilding it if needed.
214 // RequiresNullTerminator is false because module files don't need it, and
215 // this allows the file to still be mmapped.
216 Buf
= FileMgr
.getBufferForFile(NewModule
->File
,
218 /*RequiresNullTerminator=*/false);
222 ErrorStr
= Buf
.getError().message();
226 NewModule
->Buffer
= &getModuleCache().addPCM(FileName
, std::move(*Buf
));
229 // Initialize the stream.
230 NewModule
->Data
= PCHContainerRdr
.ExtractPCH(*NewModule
->Buffer
);
232 // Read the signature eagerly now so that we can check it. Avoid calling
233 // ReadSignature unless there's something to check though.
234 if (ExpectedSignature
&& checkSignature(ReadSignature(NewModule
->Data
),
235 ExpectedSignature
, ErrorStr
))
238 // We're keeping this module. Store it everywhere.
239 Module
= Modules
[Entry
] = NewModule
.get();
241 updateModuleImports(*NewModule
, ImportedBy
, ImportLoc
);
243 if (!NewModule
->isModule())
244 PCHChain
.push_back(NewModule
.get());
246 Roots
.push_back(NewModule
.get());
248 Chain
.push_back(std::move(NewModule
));
252 void ModuleManager::removeModules(ModuleIterator First
, ModuleMap
*modMap
) {
257 // Explicitly clear VisitOrder since we might not notice it is stale.
260 // Collect the set of module file pointers that we'll be removing.
261 llvm::SmallPtrSet
<ModuleFile
*, 4> victimSet(
262 (llvm::pointer_iterator
<ModuleIterator
>(First
)),
263 (llvm::pointer_iterator
<ModuleIterator
>(Last
)));
265 auto IsVictim
= [&](ModuleFile
*MF
) {
266 return victimSet
.count(MF
);
268 // Remove any references to the now-destroyed modules.
269 for (auto I
= begin(); I
!= First
; ++I
) {
270 I
->Imports
.remove_if(IsVictim
);
271 I
->ImportedBy
.remove_if(IsVictim
);
273 llvm::erase_if(Roots
, IsVictim
);
275 // Remove the modules from the PCH chain.
276 for (auto I
= First
; I
!= Last
; ++I
) {
277 if (!I
->isModule()) {
278 PCHChain
.erase(llvm::find(PCHChain
, &*I
), PCHChain
.end());
283 // Delete the modules and erase them from the various structures.
284 for (ModuleIterator victim
= First
; victim
!= Last
; ++victim
) {
285 Modules
.erase(victim
->File
);
288 StringRef ModuleName
= victim
->ModuleName
;
289 if (Module
*mod
= modMap
->findModule(ModuleName
)) {
290 mod
->setASTFile(None
);
295 // Delete the modules.
296 Chain
.erase(Chain
.begin() + (First
- begin()), Chain
.end());
300 ModuleManager::addInMemoryBuffer(StringRef FileName
,
301 std::unique_ptr
<llvm::MemoryBuffer
> Buffer
) {
302 const FileEntry
*Entry
=
303 FileMgr
.getVirtualFile(FileName
, Buffer
->getBufferSize(), 0);
304 InMemoryBuffers
[Entry
] = std::move(Buffer
);
307 std::unique_ptr
<ModuleManager::VisitState
> ModuleManager::allocateVisitState() {
308 // Fast path: if we have a cached state, use it.
309 if (FirstVisitState
) {
310 auto Result
= std::move(FirstVisitState
);
311 FirstVisitState
= std::move(Result
->NextState
);
315 // Allocate and return a new state.
316 return std::make_unique
<VisitState
>(size());
319 void ModuleManager::returnVisitState(std::unique_ptr
<VisitState
> State
) {
320 assert(State
->NextState
== nullptr && "Visited state is in list?");
321 State
->NextState
= std::move(FirstVisitState
);
322 FirstVisitState
= std::move(State
);
325 void ModuleManager::setGlobalIndex(GlobalModuleIndex
*Index
) {
328 ModulesInCommonWithGlobalIndex
.clear();
332 // Notify the global module index about all of the modules we've already
334 for (ModuleFile
&M
: *this)
335 if (!GlobalIndex
->loadedModuleFile(&M
))
336 ModulesInCommonWithGlobalIndex
.push_back(&M
);
339 void ModuleManager::moduleFileAccepted(ModuleFile
*MF
) {
340 if (!GlobalIndex
|| GlobalIndex
->loadedModuleFile(MF
))
343 ModulesInCommonWithGlobalIndex
.push_back(MF
);
346 ModuleManager::ModuleManager(FileManager
&FileMgr
,
347 InMemoryModuleCache
&ModuleCache
,
348 const PCHContainerReader
&PCHContainerRdr
,
349 const HeaderSearch
&HeaderSearchInfo
)
350 : FileMgr(FileMgr
), ModuleCache(&ModuleCache
),
351 PCHContainerRdr(PCHContainerRdr
), HeaderSearchInfo(HeaderSearchInfo
) {}
353 void ModuleManager::visit(llvm::function_ref
<bool(ModuleFile
&M
)> Visitor
,
354 llvm::SmallPtrSetImpl
<ModuleFile
*> *ModuleFilesHit
) {
355 // If the visitation order vector is the wrong size, recompute the order.
356 if (VisitOrder
.size() != Chain
.size()) {
359 VisitOrder
.reserve(N
);
361 // Record the number of incoming edges for each module. When we
362 // encounter a module with no incoming edges, push it into the queue
363 // to seed the queue.
364 SmallVector
<ModuleFile
*, 4> Queue
;
366 llvm::SmallVector
<unsigned, 4> UnusedIncomingEdges
;
367 UnusedIncomingEdges
.resize(size());
368 for (ModuleFile
&M
: llvm::reverse(*this)) {
369 unsigned Size
= M
.ImportedBy
.size();
370 UnusedIncomingEdges
[M
.Index
] = Size
;
375 // Traverse the graph, making sure to visit a module before visiting any
376 // of its dependencies.
377 while (!Queue
.empty()) {
378 ModuleFile
*CurrentModule
= Queue
.pop_back_val();
379 VisitOrder
.push_back(CurrentModule
);
381 // For any module that this module depends on, push it on the
382 // stack (if it hasn't already been marked as visited).
383 for (ModuleFile
*M
: llvm::reverse(CurrentModule
->Imports
)) {
384 // Remove our current module as an impediment to visiting the
385 // module we depend on. If we were the last unvisited module
386 // that depends on this particular module, push it into the
387 // queue to be visited.
388 unsigned &NumUnusedEdges
= UnusedIncomingEdges
[M
->Index
];
389 if (NumUnusedEdges
&& (--NumUnusedEdges
== 0))
394 assert(VisitOrder
.size() == N
&& "Visitation order is wrong?");
396 FirstVisitState
= nullptr;
399 auto State
= allocateVisitState();
400 unsigned VisitNumber
= State
->NextVisitNumber
++;
402 // If the caller has provided us with a hit-set that came from the global
403 // module index, mark every module file in common with the global module
404 // index that is *not* in that set as 'visited'.
405 if (ModuleFilesHit
&& !ModulesInCommonWithGlobalIndex
.empty()) {
406 for (unsigned I
= 0, N
= ModulesInCommonWithGlobalIndex
.size(); I
!= N
; ++I
)
408 ModuleFile
*M
= ModulesInCommonWithGlobalIndex
[I
];
409 if (!ModuleFilesHit
->count(M
))
410 State
->VisitNumber
[M
->Index
] = VisitNumber
;
414 for (unsigned I
= 0, N
= VisitOrder
.size(); I
!= N
; ++I
) {
415 ModuleFile
*CurrentModule
= VisitOrder
[I
];
416 // Should we skip this module file?
417 if (State
->VisitNumber
[CurrentModule
->Index
] == VisitNumber
)
421 assert(State
->VisitNumber
[CurrentModule
->Index
] == VisitNumber
- 1);
422 State
->VisitNumber
[CurrentModule
->Index
] = VisitNumber
;
423 if (!Visitor(*CurrentModule
))
426 // The visitor has requested that cut off visitation of any
427 // module that the current module depends on. To indicate this
428 // behavior, we mark all of the reachable modules as having been visited.
429 ModuleFile
*NextModule
= CurrentModule
;
431 // For any module that this module depends on, push it on the
432 // stack (if it hasn't already been marked as visited).
433 for (llvm::SetVector
<ModuleFile
*>::iterator
434 M
= NextModule
->Imports
.begin(),
435 MEnd
= NextModule
->Imports
.end();
437 if (State
->VisitNumber
[(*M
)->Index
] != VisitNumber
) {
438 State
->Stack
.push_back(*M
);
439 State
->VisitNumber
[(*M
)->Index
] = VisitNumber
;
443 if (State
->Stack
.empty())
446 // Pop the next module off the stack.
447 NextModule
= State
->Stack
.pop_back_val();
451 returnVisitState(std::move(State
));
454 bool ModuleManager::lookupModuleFile(StringRef FileName
, off_t ExpectedSize
,
455 time_t ExpectedModTime
,
456 Optional
<FileEntryRef
> &File
) {
461 // Open the file immediately to ensure there is no race between stat'ing and
463 Optional
<FileEntryRef
> FileOrErr
=
464 expectedToOptional(FileMgr
.getFileRef(FileName
, /*OpenFile=*/true,
465 /*CacheFailure=*/false));
471 if ((ExpectedSize
&& ExpectedSize
!= File
->getSize()) ||
472 (ExpectedModTime
&& ExpectedModTime
!= File
->getModificationTime()))
473 // Do not destroy File, as it may be referenced. If we need to rebuild it,
474 // it will be destroyed by removeModules.
484 struct GraphTraits
<ModuleManager
> {
485 using NodeRef
= ModuleFile
*;
486 using ChildIteratorType
= llvm::SetVector
<ModuleFile
*>::const_iterator
;
487 using nodes_iterator
= pointer_iterator
<ModuleManager::ModuleConstIterator
>;
489 static ChildIteratorType
child_begin(NodeRef Node
) {
490 return Node
->Imports
.begin();
493 static ChildIteratorType
child_end(NodeRef Node
) {
494 return Node
->Imports
.end();
497 static nodes_iterator
nodes_begin(const ModuleManager
&Manager
) {
498 return nodes_iterator(Manager
.begin());
501 static nodes_iterator
nodes_end(const ModuleManager
&Manager
) {
502 return nodes_iterator(Manager
.end());
507 struct DOTGraphTraits
<ModuleManager
> : public DefaultDOTGraphTraits
{
508 explicit DOTGraphTraits(bool IsSimple
= false)
509 : DefaultDOTGraphTraits(IsSimple
) {}
511 static bool renderGraphFromBottomUp() { return true; }
513 std::string
getNodeLabel(ModuleFile
*M
, const ModuleManager
&) {
514 return M
->ModuleName
;
520 void ModuleManager::viewGraph() {
521 llvm::ViewGraph(*this, "Modules");