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;
45 auto Entry = FileMgr.
getFile(Name,
false,
62 auto Known = Modules.find(
File);
63 if (Known == Modules.end())
69 std::unique_ptr<llvm::MemoryBuffer>
71 auto Entry = FileMgr.
getFile(Name,
false,
75 return std::move(InMemoryBuffers[*Entry]);
81 if (!ExpectedSignature || Signature == ExpectedSignature)
85 Signature ?
"signature mismatch" :
"could not read module signature";
93 ImportedBy->
Imports.insert(&MF);
106 off_t ExpectedSize, time_t ExpectedModTime,
126 ErrorStr =
"module file out of date";
130 if (!Entry && FileName !=
"-") {
131 ErrorStr =
"module file not found";
153 return Entry->getName() == MF->FileName;
157 if (
ModuleFile *ModuleEntry = Modules.lookup(Entry)) {
158 if (implicitModuleNamesMatch(
Type, ModuleEntry, Entry)) {
160 if (
checkSignature(ModuleEntry->Signature, ExpectedSignature, ErrorStr))
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;
178 std::string TimestampFilename = NewModule->getTimestampFilename();
179 llvm::vfs::Status Status;
182 NewModule->InputFilesValidationTimestamp =
183 llvm::sys::toTimeT(Status.getLastModificationTime());
187 if (std::unique_ptr<llvm::MemoryBuffer> Buffer =
lookupBuffer(FileName)) {
189 NewModule->Buffer = &ModuleCache->addBuiltPCM(FileName, std::move(Buffer));
194 }
else if (llvm::MemoryBuffer *Buffer =
196 NewModule->Buffer = Buffer;
206 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code()));
207 if (FileName ==
"-") {
208 Buf = llvm::MemoryBuffer::getSTDIN();
222 ErrorStr = Buf.getError().message();
230 NewModule->Data = PCHContainerRdr.
ExtractPCH(*NewModule->Buffer);
234 if (ExpectedSignature &&
checkSignature(ReadSignature(NewModule->Data),
235 ExpectedSignature, ErrorStr))
239 Module = Modules[Entry] = NewModule.get();
243 if (!NewModule->isModule())
244 PCHChain.push_back(NewModule.get());
246 Roots.push_back(NewModule.get());
248 Chain.push_back(std::move(NewModule));
262 (llvm::pointer_iterator<ModuleIterator>(
First)),
263 (llvm::pointer_iterator<ModuleIterator>(
Last)));
266 return victimSet.count(MF);
270 I->Imports.remove_if(IsVictim);
271 I->ImportedBy.remove_if(IsVictim);
273 llvm::erase_if(Roots, IsVictim);
277 if (!I->isModule()) {
278 PCHChain.erase(llvm::find(PCHChain, &*I), PCHChain.end());
285 Modules.erase(victim->File);
288 StringRef ModuleName = victim->ModuleName;
290 mod->setASTFile(None);
296 Chain.erase(Chain.begin() + (
First -
begin()), Chain.end());
301 std::unique_ptr<llvm::MemoryBuffer> Buffer) {
304 InMemoryBuffers[Entry] = std::move(Buffer);
307 std::unique_ptr<ModuleManager::VisitState> ModuleManager::allocateVisitState() {
309 if (FirstVisitState) {
310 auto Result = std::move(FirstVisitState);
311 FirstVisitState = std::move(Result->NextState);
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);
328 ModulesInCommonWithGlobalIndex.clear();
336 ModulesInCommonWithGlobalIndex.push_back(&M);
343 ModulesInCommonWithGlobalIndex.push_back(MF);
350 : FileMgr(FileMgr), ModuleCache(&ModuleCache),
351 PCHContainerRdr(PCHContainerRdr), HeaderSearchInfo(HeaderSearchInfo) {}
354 llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {
356 if (VisitOrder.size() != Chain.size()) {
359 VisitOrder.reserve(N);
367 UnusedIncomingEdges.resize(
size());
370 UnusedIncomingEdges[M.
Index] = Size;
377 while (!Queue.empty()) {
378 ModuleFile *CurrentModule = Queue.pop_back_val();
379 VisitOrder.push_back(CurrentModule);
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++;
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))
414 for (
unsigned I = 0, N = VisitOrder.size(); I != N; ++I) {
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))
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())
447 NextModule =
State->Stack.pop_back_val();
451 returnVisitState(std::move(
State));
455 time_t ExpectedModTime,
464 expectedToOptional(FileMgr.
getFileRef(FileName,
true,
471 if ((ExpectedSize && ExpectedSize !=
File->getSize()) ||
472 (ExpectedModTime && ExpectedModTime !=
File->getModificationTime()))
490 return Node->Imports.begin();
494 return Node->Imports.end();
521 llvm::ViewGraph(*
this,
"Modules");