When loading a module fails because it is out of date, rebuild that

module in place. <rdar://problem/10138913>

llvm-svn: 167539
This commit is contained in:
Douglas Gregor
2012-11-07 17:46:15 +00:00
parent b9db60fbce
commit 188dbef26d
8 changed files with 111 additions and 13 deletions

View File

@@ -88,6 +88,45 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
return std::make_pair(ModuleEntry, NewModule);
}
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) {
if (first == last)
return;
// Collect the set of module file pointers that we'll be removing.
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);
}
// Delete the modules and erase them from the various structures.
for (ModuleIterator victim = first; victim != last; ++victim) {
Modules.erase((*victim)->File);
delete *victim;
}
// Remove the modules from the chain.
Chain.erase(first, last);
}
void ModuleManager::addInMemoryBuffer(StringRef FileName,
llvm::MemoryBuffer *Buffer) {