diff options
Diffstat (limited to 'lib/Serialization/ModuleManager.cpp')
-rw-r--r-- | lib/Serialization/ModuleManager.cpp | 101 |
1 files changed, 49 insertions, 52 deletions
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp index 292f36dfeb2a..722b547e803e 100644 --- a/lib/Serialization/ModuleManager.cpp +++ b/lib/Serialization/ModuleManager.cpp @@ -11,14 +11,13 @@ // modules for the ASTReader. // //===----------------------------------------------------------------------===// +#include "clang/Serialization/ModuleManager.h" #include "clang/Frontend/PCHContainerOperations.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/ModuleMap.h" #include "clang/Serialization/GlobalModuleIndex.h" -#include "clang/Serialization/ModuleManager.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" #include <system_error> #ifndef NDEBUG @@ -67,7 +66,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, // Look for the file entry. This only fails if the expected size or // modification time differ. const FileEntry *Entry; - if (Type == MK_ExplicitModule) { + if (Type == MK_ExplicitModule || Type == MK_PrebuiltModule) { // If we're not expecting to pull this file out of the module cache, it // might have a different mtime due to being moved across filesystems in // a distributed build. The size must still match, though. (As must the @@ -85,37 +84,31 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, } // Check whether we already loaded this module, before - ModuleFile *&ModuleEntry = Modules[Entry]; + ModuleFile *ModuleEntry = Modules[Entry]; bool NewModule = false; if (!ModuleEntry) { // Allocate a new module. - ModuleFile *New = new ModuleFile(Type, Generation); - New->Index = Chain.size(); - New->FileName = FileName.str(); - New->File = Entry; - New->ImportLoc = ImportLoc; - Chain.push_back(New); - if (!New->isModule()) - PCHChain.push_back(New); - if (!ImportedBy) - Roots.push_back(New); NewModule = true; - ModuleEntry = New; - - New->InputFilesValidationTimestamp = 0; - if (New->Kind == MK_ImplicitModule) { - std::string TimestampFilename = New->getTimestampFilename(); + ModuleEntry = new ModuleFile(Type, Generation); + ModuleEntry->Index = Chain.size(); + ModuleEntry->FileName = FileName.str(); + ModuleEntry->File = Entry; + ModuleEntry->ImportLoc = ImportLoc; + ModuleEntry->InputFilesValidationTimestamp = 0; + + if (ModuleEntry->Kind == MK_ImplicitModule) { + std::string TimestampFilename = ModuleEntry->getTimestampFilename(); vfs::Status Status; // A cached stat value would be fine as well. if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status)) - New->InputFilesValidationTimestamp = - Status.getLastModificationTime().toEpochTime(); + ModuleEntry->InputFilesValidationTimestamp = + llvm::sys::toTimeT(Status.getLastModificationTime()); } // Load the contents of the module if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) { // The buffer was already provided for us. - New->Buffer = std::move(Buffer); + ModuleEntry->Buffer = std::move(Buffer); } else { // Open the AST file. llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf( @@ -127,52 +120,40 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, // ModuleManager it must be the same underlying file. // FIXME: Because FileManager::getFile() doesn't guarantee that it will // give us an open file, this may not be 100% reliable. - Buf = FileMgr.getBufferForFile(New->File, + Buf = FileMgr.getBufferForFile(ModuleEntry->File, /*IsVolatile=*/false, /*ShouldClose=*/false); } if (!Buf) { ErrorStr = Buf.getError().message(); + delete ModuleEntry; return Missing; } - New->Buffer = std::move(*Buf); + ModuleEntry->Buffer = std::move(*Buf); } // Initialize the stream. - PCHContainerRdr.ExtractPCH(New->Buffer->getMemBufferRef(), New->StreamFile); + ModuleEntry->Data = PCHContainerRdr.ExtractPCH(*ModuleEntry->Buffer); } if (ExpectedSignature) { - if (NewModule) - ModuleEntry->Signature = ReadSignature(ModuleEntry->StreamFile); - else - assert(ModuleEntry->Signature == ReadSignature(ModuleEntry->StreamFile)); + // If we've not read the control block yet, read the signature eagerly now + // so that we can check it. + if (!ModuleEntry->Signature) + ModuleEntry->Signature = ReadSignature(ModuleEntry->Data); if (ModuleEntry->Signature != ExpectedSignature) { ErrorStr = ModuleEntry->Signature ? "signature mismatch" : "could not read module signature"; - if (NewModule) { - // Remove the module file immediately, since removeModules might try to - // invalidate the file cache for Entry, and that is not safe if this - // module is *itself* up to date, but has an out-of-date importer. - Modules.erase(Entry); - assert(Chain.back() == ModuleEntry); - Chain.pop_back(); - if (!ModuleEntry->isModule()) - PCHChain.pop_back(); - if (Roots.back() == ModuleEntry) - Roots.pop_back(); - else - assert(ImportedBy); + if (NewModule) delete ModuleEntry; - } return OutOfDate; } } - + if (ImportedBy) { ModuleEntry->ImportedBy.insert(ImportedBy); ImportedBy->Imports.insert(ModuleEntry); @@ -184,7 +165,20 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, } Module = ModuleEntry; - return NewModule? NewlyLoaded : AlreadyLoaded; + + if (!NewModule) + return AlreadyLoaded; + + assert(!Modules[Entry] && "module loaded twice"); + Modules[Entry] = ModuleEntry; + + Chain.push_back(ModuleEntry); + if (!ModuleEntry->isModule()) + PCHChain.push_back(ModuleEntry); + if (!ImportedBy) + Roots.push_back(ModuleEntry); + + return NewlyLoaded; } void ModuleManager::removeModules( @@ -413,13 +407,16 @@ bool ModuleManager::lookupModuleFile(StringRef FileName, off_t ExpectedSize, time_t ExpectedModTime, const FileEntry *&File) { + if (FileName == "-") { + File = nullptr; + return false; + } + // Open the file immediately to ensure there is no race between stat'ing and // opening the file. File = FileMgr.getFile(FileName, /*openFile=*/true, /*cacheFailure=*/false); - - if (!File && FileName != "-") { + if (!File) return false; - } if ((ExpectedSize && ExpectedSize != File->getSize()) || (ExpectedModTime && ExpectedModTime != File->getModificationTime())) @@ -434,15 +431,15 @@ bool ModuleManager::lookupModuleFile(StringRef FileName, namespace llvm { template<> struct GraphTraits<ModuleManager> { - typedef ModuleFile NodeType; + typedef ModuleFile *NodeRef; typedef llvm::SetVector<ModuleFile *>::const_iterator ChildIteratorType; typedef ModuleManager::ModuleConstIterator nodes_iterator; - - static ChildIteratorType child_begin(NodeType *Node) { + + static ChildIteratorType child_begin(NodeRef Node) { return Node->Imports.begin(); } - static ChildIteratorType child_end(NodeType *Node) { + static ChildIteratorType child_end(NodeRef Node) { return Node->Imports.end(); } |