[cfe-commits] r167539 - in /cfe/trunk: include/clang/Serialization/ModuleManager.h lib/Frontend/CompilerInstance.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ModuleManager.cpp test/Modules/Inputs/Modified/ test/Modules/Inputs/Modified/A.h test/Modules/Inputs/Modified/B.h test/Modules/Inputs/Modified/module.map test/Modules/modify-module.m
Douglas Gregor
dgregor at apple.com
Wed Nov 7 09:46:16 PST 2012
Author: dgregor
Date: Wed Nov 7 11:46:15 2012
New Revision: 167539
URL: http://llvm.org/viewvc/llvm-project?rev=167539&view=rev
Log:
When loading a module fails because it is out of date, rebuild that
module in place. <rdar://problem/10138913>
Added:
cfe/trunk/test/Modules/Inputs/Modified/
cfe/trunk/test/Modules/Inputs/Modified/A.h (with props)
cfe/trunk/test/Modules/Inputs/Modified/B.h (with props)
cfe/trunk/test/Modules/Inputs/Modified/module.map
cfe/trunk/test/Modules/modify-module.m
Modified:
cfe/trunk/include/clang/Serialization/ModuleManager.h
cfe/trunk/lib/Frontend/CompilerInstance.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ModuleManager.cpp
Modified: cfe/trunk/include/clang/Serialization/ModuleManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ModuleManager.h?rev=167539&r1=167538&r2=167539&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ModuleManager.h (original)
+++ cfe/trunk/include/clang/Serialization/ModuleManager.h Wed Nov 7 11:46:15 2012
@@ -105,7 +105,10 @@
std::pair<ModuleFile *, bool>
addModule(StringRef FileName, ModuleKind Type, ModuleFile *ImportedBy,
unsigned Generation, std::string &ErrorStr);
-
+
+ /// \brief Remove the given set of modules.
+ void removeModules(ModuleIterator first, ModuleIterator last);
+
/// \brief Add an in-memory buffer the list of known buffers
void addInMemoryBuffer(StringRef FileName, llvm::MemoryBuffer *Buffer);
Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=167539&r1=167538&r2=167539&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Wed Nov 7 11:46:15 2012
@@ -762,7 +762,7 @@
// Someone else is responsible for building the module. Wait for them to
// finish.
Locked.waitForUnlock();
- break;
+ return;
}
ModuleMap &ModMap
@@ -975,13 +975,36 @@
}
// Try to load the module we found.
+ unsigned ARRFlags = ASTReader::ARR_None;
+ if (Module)
+ ARRFlags |= ASTReader::ARR_OutOfDate;
switch (ModuleManager->ReadAST(ModuleFile->getName(),
serialization::MK_Module,
- ASTReader::ARR_None)) {
+ ARRFlags)) {
case ASTReader::Success:
break;
- case ASTReader::OutOfDate:
+ case ASTReader::OutOfDate: {
+ // The module file is out-of-date. Rebuild it.
+ getFileManager().invalidateCache(ModuleFile);
+ bool Existed;
+ llvm::sys::fs::remove(ModuleFileName, Existed);
+ compileModule(*this, Module, ModuleFileName);
+
+ // Try loading the module again.
+ ModuleFile = FileMgr->getFile(ModuleFileName);
+ if (!ModuleFile ||
+ ModuleManager->ReadAST(ModuleFileName,
+ serialization::MK_Module,
+ ASTReader::ARR_None) != ASTReader::Success) {
+ KnownModules[Path[0].first] = 0;
+ return 0;
+ }
+
+ // Okay, we've rebuilt and now loaded the module.
+ break;
+ }
+
case ASTReader::VersionMismatch:
case ASTReader::ConfigurationMismatch:
case ASTReader::HadErrors:
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=167539&r1=167538&r2=167539&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Nov 7 11:46:15 2012
@@ -2675,16 +2675,21 @@
// Bump the generation number.
unsigned PreviousGeneration = CurrentGeneration++;
- // Load the core of the AST files.
+ unsigned NumModules = ModuleMgr.size();
llvm::SmallVector<ModuleFile *, 4> Loaded;
- switch(ReadASTCore(FileName, Type, /*ImportedBy=*/0, Loaded,
- ClientLoadCapabilities)) {
- case Failure: return Failure;
- case OutOfDate: return OutOfDate;
- case VersionMismatch: return VersionMismatch;
- case ConfigurationMismatch: return ConfigurationMismatch;
- case HadErrors: return HadErrors;
- case Success: break;
+ switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type,
+ /*ImportedBy=*/0, Loaded,
+ ClientLoadCapabilities)) {
+ case Failure:
+ case OutOfDate:
+ case VersionMismatch:
+ case ConfigurationMismatch:
+ case HadErrors:
+ ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end());
+ return ReadResult;
+
+ case Success:
+ break;
}
// Here comes stuff that we only do once the entire chain is loaded.
Modified: cfe/trunk/lib/Serialization/ModuleManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=167539&r1=167538&r2=167539&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ModuleManager.cpp (original)
+++ cfe/trunk/lib/Serialization/ModuleManager.cpp Wed Nov 7 11:46:15 2012
@@ -88,6 +88,45 @@
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) {
Added: cfe/trunk/test/Modules/Inputs/Modified/A.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/Modified/A.h?rev=167539&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/Modified/A.h (added)
+++ cfe/trunk/test/Modules/Inputs/Modified/A.h Wed Nov 7 11:46:15 2012
@@ -0,0 +1 @@
+int getA();
Propchange: cfe/trunk/test/Modules/Inputs/Modified/A.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/Modules/Inputs/Modified/A.h
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/Modules/Inputs/Modified/A.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cfe/trunk/test/Modules/Inputs/Modified/B.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/Modified/B.h?rev=167539&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/Modified/B.h (added)
+++ cfe/trunk/test/Modules/Inputs/Modified/B.h Wed Nov 7 11:46:15 2012
@@ -0,0 +1,2 @@
+#include "A.h"
+int getB();
Propchange: cfe/trunk/test/Modules/Inputs/Modified/B.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/Modules/Inputs/Modified/B.h
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/Modules/Inputs/Modified/B.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cfe/trunk/test/Modules/Inputs/Modified/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/Modified/module.map?rev=167539&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/Modified/module.map (added)
+++ cfe/trunk/test/Modules/Inputs/Modified/module.map Wed Nov 7 11:46:15 2012
@@ -0,0 +1,2 @@
+module A { header "A.h" }
+module B { header "B.h" }
Added: cfe/trunk/test/Modules/modify-module.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/modify-module.m?rev=167539&view=auto
==============================================================================
--- cfe/trunk/test/Modules/modify-module.m (added)
+++ cfe/trunk/test/Modules/modify-module.m Wed Nov 7 11:46:15 2012
@@ -0,0 +1,23 @@
+// Test that if we modify one of the input files used to form a
+// header, that module and dependent modules get rebuilt.
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/include
+// RUN: cp %S/Inputs/Modified/A.h %t/include
+// RUN: cp %S/Inputs/Modified/B.h %t/include
+// RUN: cp %S/Inputs/Modified/module.map %t/include
+// RUN: %clang_cc1 -fmodule-cache-path %t/cache -fmodules -I %t/include %s -verify
+// expected-no-diagnostics
+// RUN: touch %t/include/B.h
+// RUN: %clang_cc1 -fmodule-cache-path %t/cache -fmodules -I %t/include %s -verify
+// RUN: echo 'int getA(); int getA2();' > %t/include/A.h
+// RUN: %clang_cc1 -fmodule-cache-path %t/cache -fmodules -I %t/include %s -verify
+
+ at __experimental_modules_import B;
+
+int getValue() { return getA() + getB(); }
+
+
+
+
+
More information about the cfe-commits
mailing list