diff options
author | Eli Bendersky <eliben@chromium.org> | 2013-07-15 16:08:08 -0700 |
---|---|---|
committer | Eli Bendersky <eliben@chromium.org> | 2013-07-15 16:08:08 -0700 |
commit | e789858899a7b36caf11b371a97411a1582a482b (patch) | |
tree | e8c28b178b32010f73b477b3c65b5ff74437530c /lib/Serialization/ModuleManager.cpp | |
parent | 99a5501f5ae5b75017dfc386d4abf648234e85df (diff) | |
parent | 20c7d45a4da9f58ad805ad1d37f92fe7dc232ec8 (diff) |
Merge commit '20c7d45a4da9f58ad805ad1d37f92fe7dc232ec8'
Conflicts:
lib/CodeGen/ItaniumCXXABI.cpp
Diffstat (limited to 'lib/Serialization/ModuleManager.cpp')
-rw-r--r-- | lib/Serialization/ModuleManager.cpp | 128 |
1 files changed, 86 insertions, 42 deletions
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp index b9f4d888f3..f3d53adafa 100644 --- a/lib/Serialization/ModuleManager.cpp +++ b/lib/Serialization/ModuleManager.cpp @@ -11,9 +11,11 @@ // modules for the ASTReader. // //===----------------------------------------------------------------------===// +#include "clang/Lex/ModuleMap.h" #include "clang/Serialization/ModuleManager.h" #include "clang/Serialization/GlobalModuleIndex.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/PathV2.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" @@ -27,7 +29,19 @@ using namespace serialization; ModuleFile *ModuleManager::lookup(StringRef Name) { const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false, /*cacheFailure=*/false); - return Modules[Entry]; + if (Entry) + return lookup(Entry); + + return 0; +} + +ModuleFile *ModuleManager::lookup(const FileEntry *File) { + llvm::DenseMap<const FileEntry *, ModuleFile *>::iterator Known + = Modules.find(File); + if (Known == Modules.end()) + return 0; + + return Known->second; } llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) { @@ -36,18 +50,27 @@ llvm::MemoryBuffer *ModuleManager::lookupBuffer(StringRef Name) { return InMemoryBuffers[Entry]; } -std::pair<ModuleFile *, bool> +ModuleManager::AddModuleResult ModuleManager::addModule(StringRef FileName, ModuleKind Type, SourceLocation ImportLoc, ModuleFile *ImportedBy, - unsigned Generation, std::string &ErrorStr) { - const FileEntry *Entry = FileMgr.getFile(FileName, /*openFile=*/false, - /*cacheFailure=*/false); + unsigned Generation, + off_t ExpectedSize, time_t ExpectedModTime, + ModuleFile *&Module, + std::string &ErrorStr) { + Module = 0; + + // Look for the file entry. This only fails if the expected size or + // modification time differ. + const FileEntry *Entry; + if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) + return OutOfDate; + if (!Entry && FileName != "-") { ErrorStr = "file not found"; - return std::make_pair(static_cast<ModuleFile*>(0), false); + return Missing; } - - // Check whether we already loaded this module, before + + // Check whether we already loaded this module, before ModuleFile *&ModuleEntry = Modules[Entry]; bool NewModule = false; if (!ModuleEntry) { @@ -77,12 +100,13 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr)); if (!New->Buffer) - return std::make_pair(static_cast<ModuleFile*>(0), false); + return Missing; } // Initialize the stream New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(), - (const unsigned char *)New->Buffer->getBufferEnd()); } + (const unsigned char *)New->Buffer->getBufferEnd()); + } if (ImportedBy) { ModuleEntry->ImportedBy.insert(ImportedBy); @@ -93,8 +117,9 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, ModuleEntry->DirectlyImported = true; } - - return std::make_pair(ModuleEntry, NewModule); + + Module = ModuleEntry; + return NewModule? NewlyLoaded : AlreadyLoaded; } namespace { @@ -113,7 +138,8 @@ namespace { }; } -void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last) { +void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last, + ModuleMap *modMap) { if (first == last) return; @@ -129,6 +155,14 @@ void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last) { // Delete the modules and erase them from the various structures. for (ModuleIterator victim = first; victim != last; ++victim) { Modules.erase((*victim)->File); + + FileMgr.invalidateCache((*victim)->File); + if (modMap) { + StringRef ModuleName = llvm::sys::path::stem((*victim)->FileName); + if (Module *mod = modMap->findModule(ModuleName)) { + mod->setASTFile(0); + } + } delete *victim; } @@ -144,27 +178,6 @@ void ModuleManager::addInMemoryBuffer(StringRef FileName, InMemoryBuffers[Entry] = Buffer; } -void ModuleManager::updateModulesInCommonWithGlobalIndex() { - ModulesInCommonWithGlobalIndex.clear(); - - if (!GlobalIndex) - return; - - // Collect the set of modules known to the global index. - SmallVector<const FileEntry *, 16> KnownModules; - GlobalIndex->getKnownModules(KnownModules); - - // Map those modules to AST files known to the module manager. - for (unsigned I = 0, N = KnownModules.size(); I != N; ++I) { - llvm::DenseMap<const FileEntry *, ModuleFile *>::iterator Known - = Modules.find(KnownModules[I]); - if (Known == Modules.end()) - continue; - - ModulesInCommonWithGlobalIndex.push_back(Known->second); - } -} - ModuleManager::VisitState *ModuleManager::allocateVisitState() { // Fast path: if we have a cached state, use it. if (FirstVisitState) { @@ -186,7 +199,25 @@ void ModuleManager::returnVisitState(VisitState *State) { void ModuleManager::setGlobalIndex(GlobalModuleIndex *Index) { GlobalIndex = Index; - updateModulesInCommonWithGlobalIndex(); + if (!GlobalIndex) { + ModulesInCommonWithGlobalIndex.clear(); + return; + } + + // Notify the global module index about all of the modules we've already + // loaded. + for (unsigned I = 0, N = Chain.size(); I != N; ++I) { + if (!GlobalIndex->loadedModuleFile(Chain[I])) { + ModulesInCommonWithGlobalIndex.push_back(Chain[I]); + } + } +} + +void ModuleManager::moduleFileAccepted(ModuleFile *MF) { + if (!GlobalIndex || GlobalIndex->loadedModuleFile(MF)) + return; + + ModulesInCommonWithGlobalIndex.push_back(MF); } ModuleManager::ModuleManager(FileManager &FileMgr) @@ -201,7 +232,7 @@ ModuleManager::~ModuleManager() { void ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData, - llvm::SmallPtrSet<const FileEntry *, 4> *ModuleFilesHit) { + llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit) { // If the visitation order vector is the wrong size, recompute the order. if (VisitOrder.size() != Chain.size()) { unsigned N = size(); @@ -249,11 +280,6 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), assert(VisitOrder.size() == N && "Visitation order is wrong?"); - // We may need to update the set of modules we have in common with the - // global module index, since modules could have been added to the module - // manager since we loaded the global module index. - updateModulesInCommonWithGlobalIndex(); - delete FirstVisitState; FirstVisitState = 0; } @@ -268,7 +294,7 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), for (unsigned I = 0, N = ModulesInCommonWithGlobalIndex.size(); I != N; ++I) { ModuleFile *M = ModulesInCommonWithGlobalIndex[I]; - if (!ModuleFilesHit->count(M->File)) + if (!ModuleFilesHit->count(M)) State->VisitNumber[M->Index] = VisitNumber; } } @@ -354,6 +380,24 @@ void ModuleManager::visitDepthFirst(bool (*Visitor)(ModuleFile &M, bool Preorder } } +bool ModuleManager::lookupModuleFile(StringRef FileName, + off_t ExpectedSize, + time_t ExpectedModTime, + const FileEntry *&File) { + File = FileMgr.getFile(FileName, /*openFile=*/false, /*cacheFailure=*/false); + + if (!File && FileName != "-") { + return false; + } + + if ((ExpectedSize && ExpectedSize != File->getSize()) || + (ExpectedModTime && ExpectedModTime != File->getModificationTime())) { + return true; + } + + return false; +} + #ifndef NDEBUG namespace llvm { template<> |