diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 | 
| commit | 9f4dbff6669c8037f3b036bcf580d14f1a4f12a5 (patch) | |
| tree | 47df2c12b57214af6c31e47404b005675b8b7ffc /lib/Serialization/ModuleManager.cpp | |
| parent | f73d5f23a889b93d89ddef61ac0995df40286bb8 (diff) | |
Notes
Diffstat (limited to 'lib/Serialization/ModuleManager.cpp')
| -rw-r--r-- | lib/Serialization/ModuleManager.cpp | 96 | 
1 files changed, 57 insertions, 39 deletions
| diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp index 9c4b3d92befe..2c10c119a07b 100644 --- a/lib/Serialization/ModuleManager.cpp +++ b/lib/Serialization/ModuleManager.cpp @@ -11,13 +11,14 @@  //  modules for the ASTReader.  //  //===----------------------------------------------------------------------===// +#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 "llvm/Support/system_error.h" +#include <system_error>  #ifndef NDEBUG  #include "llvm/Support/GraphWriter.h" @@ -32,14 +33,14 @@ ModuleFile *ModuleManager::lookup(StringRef Name) {    if (Entry)      return lookup(Entry); -  return 0; +  return nullptr;  }  ModuleFile *ModuleManager::lookup(const FileEntry *File) {    llvm::DenseMap<const FileEntry *, ModuleFile *>::iterator Known      = Modules.find(File);    if (Known == Modules.end()) -    return 0; +    return nullptr;    return Known->second;  } @@ -57,7 +58,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,                           off_t ExpectedSize, time_t ExpectedModTime,                           ModuleFile *&Module,                           std::string &ErrorStr) { -  Module = 0; +  Module = nullptr;    // Look for the file entry. This only fails if the expected size or    // modification time differ. @@ -86,6 +87,16 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,      NewModule = true;      ModuleEntry = New; +    New->InputFilesValidationTimestamp = 0; +    if (New->Kind == MK_Module) { +      std::string TimestampFilename = New->getTimestampFilename(); +      vfs::Status Status; +      // A cached stat value would be fine as well. +      if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status)) +        New->InputFilesValidationTimestamp = +            Status.getLastModificationTime().toEpochTime(); +    } +      // Load the contents of the module      if (llvm::MemoryBuffer *Buffer = lookupBuffer(FileName)) {        // The buffer was already provided for us. @@ -93,13 +104,24 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,        New->Buffer.reset(Buffer);      } else {        // Open the AST file. -      llvm::error_code ec; +      std::error_code ec;        if (FileName == "-") { -        ec = llvm::MemoryBuffer::getSTDIN(New->Buffer); +        llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf = +            llvm::MemoryBuffer::getSTDIN(); +        ec = Buf.getError();          if (ec)            ErrorStr = ec.message(); -      } else -        New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr)); +        else +          New->Buffer = std::move(Buf.get()); +      } else { +        // Leave the FileEntry open so if it gets read again by another +        // 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. +        New->Buffer.reset(FileMgr.getBufferForFile(New->File, &ErrorStr, +                                                   /*IsVolatile*/false, +                                                   /*ShouldClose*/false)); +      }        if (!New->Buffer)          return Missing; @@ -124,24 +146,10 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,    return NewModule? NewlyLoaded : AlreadyLoaded;  } -namespace { -  /// \brief Predicate that checks whether a module file occurs within -  /// the given set. -  class IsInModuleFileSet : public std::unary_function<ModuleFile *, bool> { -    llvm::SmallPtrSet<ModuleFile *, 4> &Removed; - -  public: -    IsInModuleFileSet(llvm::SmallPtrSet<ModuleFile *, 4> &Removed) -    : Removed(Removed) { } - -    bool operator()(ModuleFile *MF) const { -      return Removed.count(MF); -    } -  }; -} - -void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last, -                                  ModuleMap *modMap) { +void ModuleManager::removeModules( +    ModuleIterator first, ModuleIterator last, +    llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully, +    ModuleMap *modMap) {    if (first == last)      return; @@ -149,22 +157,29 @@ void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last,    llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last);    // Remove any references to the now-destroyed modules. -  IsInModuleFileSet checkInSet(victimSet);    for (unsigned i = 0, n = Chain.size(); i != n; ++i) { -    Chain[i]->ImportedBy.remove_if(checkInSet); +    Chain[i]->ImportedBy.remove_if([&](ModuleFile *MF) { +      return victimSet.count(MF); +    });    }    // 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); +      StringRef ModuleName = (*victim)->ModuleName;        if (Module *mod = modMap->findModule(ModuleName)) { -        mod->setASTFile(0); +        mod->setASTFile(nullptr);        }      } + +    // Files that didn't make it through ReadASTCore successfully will be +    // rebuilt (or there was an error). Invalidate them so that we can load the +    // new files that will be renamed over the old ones. +    if (LoadedSuccessfully.count(*victim) == 0) +      FileMgr.invalidateCache((*victim)->File); +      delete *victim;    } @@ -185,7 +200,7 @@ ModuleManager::VisitState *ModuleManager::allocateVisitState() {    if (FirstVisitState) {      VisitState *Result = FirstVisitState;      FirstVisitState = FirstVisitState->NextState; -    Result->NextState = 0; +    Result->NextState = nullptr;      return Result;    } @@ -194,7 +209,7 @@ ModuleManager::VisitState *ModuleManager::allocateVisitState() {  }  void ModuleManager::returnVisitState(VisitState *State) { -  assert(State->NextState == 0 && "Visited state is in list?"); +  assert(State->NextState == nullptr && "Visited state is in list?");    State->NextState = FirstVisitState;    FirstVisitState = State;  } @@ -223,7 +238,7 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) {  }  ModuleManager::ModuleManager(FileManager &FileMgr) -  : FileMgr(FileMgr), GlobalIndex(), FirstVisitState(0) { } +  : FileMgr(FileMgr), GlobalIndex(), FirstVisitState(nullptr) {}  ModuleManager::~ModuleManager() {    for (unsigned i = 0, e = Chain.size(); i != e; ++i) @@ -283,7 +298,7 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData),      assert(VisitOrder.size() == N && "Visitation order is wrong?");      delete FirstVisitState; -    FirstVisitState = 0; +    FirstVisitState = nullptr;    }    VisitState *State = allocateVisitState(); @@ -385,16 +400,19 @@ bool ModuleManager::lookupModuleFile(StringRef FileName,                                       off_t ExpectedSize,                                       time_t ExpectedModTime,                                       const FileEntry *&File) { -  File = FileMgr.getFile(FileName, /*openFile=*/false, /*cacheFailure=*/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 != "-") {      return false;    }    if ((ExpectedSize && ExpectedSize != File->getSize()) || -      (ExpectedModTime && ExpectedModTime != File->getModificationTime())) { +      (ExpectedModTime && ExpectedModTime != File->getModificationTime())) +    // Do not destroy File, as it may be referenced. If we need to rebuild it, +    // it will be destroyed by removeModules.      return true; -  }    return false;  } @@ -434,7 +452,7 @@ namespace llvm {      }      std::string getNodeLabel(ModuleFile *M, const ModuleManager&) { -      return llvm::sys::path::stem(M->FileName); +      return M->ModuleName;      }    };  } | 
