[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