diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index c8ffd32..3079a06 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -105,6 +105,9 @@ class CompilerInstance : public ModuleLoader {
   /// \brief The ASTReader, if one exists.
   IntrusiveRefCntPtr<ASTReader> ModuleManager;
 
+  /// \brief The dependency file generator.
+  OwningPtr<DependencyFileGenerator> TheDependencyFileGenerator;
+
   /// \brief The set of top-level modules that has already been loaded,
   /// along with the module map
   llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 471d9ac..63eecb1 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -30,6 +30,7 @@ class ArgList;
 
 namespace clang {
 class ASTConsumer;
+class ASTReader;
 class CompilerInstance;
 class CompilerInvocation;
 class Decl;
@@ -72,10 +73,18 @@ void ProcessWarningOptions(DiagnosticsEngine &Diags,
 void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
                               const PreprocessorOutputOptions &Opts);
 
-/// AttachDependencyFileGen - Create a dependency file generator, and attach
-/// it to the given preprocessor.  This takes ownership of the output stream.
-void AttachDependencyFileGen(Preprocessor &PP,
-                             const DependencyOutputOptions &Opts);
+/// Builds a depdenency file when attached to a Preprocessor (for includes) and
+/// ASTReader (for module imports), and writes it out at the end of processing
+/// a source file.  Users should attach to the ast reader whenever a module is
+/// loaded.
+class DependencyFileGenerator {
+  void *Impl; // Opaque implementation
+  DependencyFileGenerator(void *Impl);
+public:
+  static DependencyFileGenerator *CreateAndAttachToPreprocessor(
+    Preprocessor &PP, const DependencyOutputOptions &Opts);
+  void AttachToASTReader(ASTReader &R);
+};
 
 /// AttachDependencyGraphGen - Create a dependency graph generator, and attach
 /// it to the given preprocessor.
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 040243c..bc9468c 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -182,6 +182,37 @@ public:
   virtual bool visitInputFile(StringRef Filename, bool isSystem) { return true;}
 };
 
+/// \brief Simple wrapper class for chaining listeners.
+class ChainedASTReaderListener : public ASTReaderListener {
+  OwningPtr<ASTReaderListener> First;
+  OwningPtr<ASTReaderListener> Second;
+public:
+  /// Takes ownership of \p First and \p Second.
+  ChainedASTReaderListener(ASTReaderListener *First, ASTReaderListener *Second)
+      : First(First), Second(Second) { }
+
+  virtual bool ReadFullVersionInformation(StringRef FullVersion);
+  virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
+                                   bool Complain);
+  virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
+                                 bool Complain);
+  virtual bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts,
+                                     bool Complain);
+  virtual bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
+                                     bool Complain);
+
+  virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+                                       bool Complain);
+  virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
+                                       bool Complain,
+                                       std::string &SuggestedPredefines);
+
+  virtual void ReadCounter(const serialization::ModuleFile &M,
+                           unsigned Value);
+  virtual bool needsInputFileVisitation();
+  virtual bool visitInputFile(StringRef Filename, bool isSystem);
+};
+
 /// \brief ASTReaderListener implementation to validate the information of
 /// the PCH file against an initialized Preprocessor.
 class PCHValidator : public ASTReaderListener {
@@ -509,7 +540,7 @@ private:
       assert(getKind() == Macro && "Hidden name is not a macro!");
       return std::make_pair(Id, MMI);
     }
-};
+  };
 
   typedef llvm::SmallDenseMap<IdentifierInfo*,
                               ModuleMacroInfo*> HiddenMacrosMap;
@@ -988,6 +1019,13 @@ private:
   /// \brief Reads a statement from the specified cursor.
   Stmt *ReadStmtFromStream(ModuleFile &F);
 
+  /// \brief Reads the stored information about an input file.
+  void readInputFileInfo(ModuleFile &F, unsigned ID, std::string &Filename,
+                         off_t &StoredSize, time_t &StoredTime,
+                         bool &Overridden);
+  /// \brief A convenience method to read the filename from an input file.
+  std::string getInputFileName(ModuleFile &F, unsigned ID);
+
   /// \brief Retrieve the file entry and 'overridden' bit for an input
   /// file in the given module file.
   serialization::InputFile getInputFile(ModuleFile &F, unsigned ID,
@@ -1277,6 +1315,15 @@ public:
     Listener.reset(listener);
   }
 
+  /// \brief Add an AST callbak listener.
+  ///
+  /// Takes ownership of \p L.
+  void addListener(ASTReaderListener *L) {
+    if (Listener)
+      L = new ChainedASTReaderListener(L, Listener.take());
+    Listener.reset(L);
+  }
+
   /// \brief Set the AST deserialization listener.
   void setDeserializationListener(ASTDeserializationListener *Listener);
 
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index e07eb52..f10311a 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -269,7 +269,8 @@ void CompilerInstance::createPreprocessor() {
   // Handle generating dependencies, if requested.
   const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
   if (!DepOpts.OutputFile.empty())
-    AttachDependencyFileGen(*PP, DepOpts);
+    TheDependencyFileGenerator.reset(
+        DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts));
   if (!DepOpts.DOTOutputFile.empty())
     AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
                              getHeaderSearchOpts().Sysroot);
@@ -1160,6 +1161,9 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
         ModuleManager->StartTranslationUnit(&getASTConsumer());
     }
 
+    if (TheDependencyFileGenerator)
+      TheDependencyFileGenerator->AttachToASTReader(*ModuleManager);
+
     // Try to load the module file.
     unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
     switch (ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module,
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index 39ccdd7..50695df 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -20,6 +20,7 @@
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/PPCallbacks.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Serialization/ASTReader.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -28,7 +29,8 @@
 using namespace clang;
 
 namespace {
-class DependencyFileCallback : public PPCallbacks {
+/// Private implementation for DependencyFileGenerator
+class DFGImpl : public PPCallbacks {
   std::vector<std::string> Files;
   llvm::StringSet<> FilesSet;
   const Preprocessor *PP;
@@ -41,12 +43,10 @@ class DependencyFileCallback : public PPCallbacks {
 private:
   bool FileMatchesDepCriteria(const char *Filename,
                               SrcMgr::CharacteristicKind FileType);
-  void AddFilename(StringRef Filename);
   void OutputDependencyFile();
 
 public:
-  DependencyFileCallback(const Preprocessor *_PP,
-                         const DependencyOutputOptions &Opts)
+  DFGImpl(const Preprocessor *_PP, const DependencyOutputOptions &Opts)
     : PP(_PP), OutputFile(Opts.OutputFile), Targets(Opts.Targets),
       IncludeSystemHeaders(Opts.IncludeSystemHeaders),
       PhonyTarget(Opts.UsePhonyTargets),
@@ -69,27 +69,51 @@ public:
   virtual void EndOfMainFile() {
     OutputDependencyFile();
   }
+
+  void AddFilename(StringRef Filename);
+  bool includeSystemHeaders() const { return IncludeSystemHeaders; }
+};
+
+class DFGASTReaderListener : public ASTReaderListener {
+  DFGImpl &Parent;
+public:
+  DFGASTReaderListener(DFGImpl &Parent)
+  : Parent(Parent) { }
+  virtual bool needsInputFileVisitation() { return true; }
+  virtual bool visitInputFile(StringRef Filename, bool isSystem);
 };
 }
 
-void clang::AttachDependencyFileGen(Preprocessor &PP,
-                                    const DependencyOutputOptions &Opts) {
+DependencyFileGenerator::DependencyFileGenerator(void *Impl)
+: Impl(Impl) { }
+
+DependencyFileGenerator *DependencyFileGenerator::CreateAndAttachToPreprocessor(
+    clang::Preprocessor &PP, const clang::DependencyOutputOptions &Opts) {
+
   if (Opts.Targets.empty()) {
     PP.getDiagnostics().Report(diag::err_fe_dependency_file_requires_MT);
-    return;
+    return NULL;
   }
 
   // Disable the "file not found" diagnostic if the -MG option was given.
   if (Opts.AddMissingHeaderDeps)
     PP.SetSuppressIncludeNotFoundError(true);
 
-  PP.addPPCallbacks(new DependencyFileCallback(&PP, Opts));
+  DFGImpl *Callback = new DFGImpl(&PP, Opts);
+  PP.addPPCallbacks(Callback); // PP owns the Callback
+  return new DependencyFileGenerator(Callback);
+}
+
+void DependencyFileGenerator::AttachToASTReader(ASTReader &R) {
+  DFGImpl *I = reinterpret_cast<DFGImpl *>(Impl);
+  assert(I && "missing implementation");
+  R.addListener(new DFGASTReaderListener(*I));
 }
 
 /// FileMatchesDepCriteria - Determine whether the given Filename should be
 /// considered as a dependency.
-bool DependencyFileCallback::FileMatchesDepCriteria(const char *Filename,
-                                          SrcMgr::CharacteristicKind FileType) {
+bool DFGImpl::FileMatchesDepCriteria(const char *Filename,
+                                     SrcMgr::CharacteristicKind FileType) {
   if (strcmp("<built-in>", Filename) == 0)
     return false;
 
@@ -99,10 +123,10 @@ bool DependencyFileCallback::FileMatchesDepCriteria(const char *Filename,
   return FileType == SrcMgr::C_User;
 }
 
-void DependencyFileCallback::FileChanged(SourceLocation Loc,
-                                         FileChangeReason Reason,
-                                         SrcMgr::CharacteristicKind FileType,
-                                         FileID PrevFID) {
+void DFGImpl::FileChanged(SourceLocation Loc,
+                          FileChangeReason Reason,
+                          SrcMgr::CharacteristicKind FileType,
+                          FileID PrevFID) {
   if (Reason != PPCallbacks::EnterFile)
     return;
 
@@ -130,15 +154,15 @@ void DependencyFileCallback::FileChanged(SourceLocation Loc,
   AddFilename(Filename);
 }
 
-void DependencyFileCallback::InclusionDirective(SourceLocation HashLoc,
-                                                const Token &IncludeTok,
-                                                StringRef FileName,
-                                                bool IsAngled,
-                                                CharSourceRange FilenameRange,
-                                                const FileEntry *File,
-                                                StringRef SearchPath,
-                                                StringRef RelativePath,
-                                                const Module *Imported) {
+void DFGImpl::InclusionDirective(SourceLocation HashLoc,
+                                 const Token &IncludeTok,
+                                 StringRef FileName,
+                                 bool IsAngled,
+                                 CharSourceRange FilenameRange,
+                                 const FileEntry *File,
+                                 StringRef SearchPath,
+                                 StringRef RelativePath,
+                                 const Module *Imported) {
   if (!File) {
     if (AddMissingHeaderDeps)
       AddFilename(FileName);
@@ -147,7 +171,7 @@ void DependencyFileCallback::InclusionDirective(SourceLocation HashLoc,
   }
 }
 
-void DependencyFileCallback::AddFilename(StringRef Filename) {
+void DFGImpl::AddFilename(StringRef Filename) {
   if (FilesSet.insert(Filename))
     Files.push_back(Filename);
 }
@@ -164,7 +188,7 @@ static void PrintFilename(raw_ostream &OS, StringRef Filename) {
   }
 }
 
-void DependencyFileCallback::OutputDependencyFile() {
+void DFGImpl::OutputDependencyFile() {
   if (SeenMissingHeader) {
     llvm::sys::fs::remove(OutputFile);
     return;
@@ -234,3 +258,10 @@ void DependencyFileCallback::OutputDependencyFile() {
   }
 }
 
+bool DFGASTReaderListener::visitInputFile(llvm::StringRef Filename,
+                                          bool IsSystem) {
+  if (!IsSystem || Parent.includeSystemHeaders())
+    Parent.AddFilename(Filename);
+  return true;
+}
+
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 86ffa52..3343301 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -2212,7 +2212,8 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) {
     return Known->second;
 
   assert(Target != 0 && "Missing target information");
-  FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
+  auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
+  FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
   const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
   if (!Buffer)
     return ParsedModuleMap[File] = true;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 41c532e..0cc38bd 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -60,6 +60,66 @@ using namespace clang::serialization;
 using namespace clang::serialization::reader;
 using llvm::BitstreamCursor;
 
+
+//===----------------------------------------------------------------------===//
+// ChainedASTReaderListener implementation
+//===----------------------------------------------------------------------===//
+
+bool
+ChainedASTReaderListener::ReadFullVersionInformation(StringRef FullVersion) {
+  return First->ReadFullVersionInformation(FullVersion) ||
+         Second->ReadFullVersionInformation(FullVersion);
+}
+bool ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts,
+                                                   bool Complain) {
+  return First->ReadLanguageOptions(LangOpts, Complain) ||
+         Second->ReadLanguageOptions(LangOpts, Complain);
+}
+bool
+ChainedASTReaderListener::ReadTargetOptions(const TargetOptions &TargetOpts,
+                                            bool Complain) {
+  return First->ReadTargetOptions(TargetOpts, Complain) ||
+         Second->ReadTargetOptions(TargetOpts, Complain);
+}
+bool ChainedASTReaderListener::ReadDiagnosticOptions(
+    const DiagnosticOptions &DiagOpts, bool Complain) {
+  return First->ReadDiagnosticOptions(DiagOpts, Complain) ||
+         Second->ReadDiagnosticOptions(DiagOpts, Complain);
+}
+bool
+ChainedASTReaderListener::ReadFileSystemOptions(const FileSystemOptions &FSOpts,
+                                                bool Complain) {
+  return First->ReadFileSystemOptions(FSOpts, Complain) ||
+         Second->ReadFileSystemOptions(FSOpts, Complain);
+}
+
+bool ChainedASTReaderListener::ReadHeaderSearchOptions(
+    const HeaderSearchOptions &HSOpts, bool Complain) {
+  return First->ReadHeaderSearchOptions(HSOpts, Complain) ||
+         Second->ReadHeaderSearchOptions(HSOpts, Complain);
+}
+bool ChainedASTReaderListener::ReadPreprocessorOptions(
+    const PreprocessorOptions &PPOpts, bool Complain,
+    std::string &SuggestedPredefines) {
+  return First->ReadPreprocessorOptions(PPOpts, Complain,
+                                        SuggestedPredefines) ||
+         Second->ReadPreprocessorOptions(PPOpts, Complain, SuggestedPredefines);
+}
+void ChainedASTReaderListener::ReadCounter(const serialization::ModuleFile &M,
+                                           unsigned Value) {
+  First->ReadCounter(M, Value);
+  Second->ReadCounter(M, Value);
+}
+bool ChainedASTReaderListener::needsInputFileVisitation() {
+  return First->needsInputFileVisitation() ||
+         Second->needsInputFileVisitation();
+}
+bool ChainedASTReaderListener::visitInputFile(StringRef Filename,
+                                              bool isSystem) {
+  return First->visitInputFile(Filename, isSystem) ||
+         Second->visitInputFile(Filename, isSystem);
+}
+
 //===----------------------------------------------------------------------===//
 // PCH validator implementation
 //===----------------------------------------------------------------------===//
@@ -1803,6 +1863,40 @@ void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
   PP.appendMacroDirective(II, MD);
 }
 
+void ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID,
+                                 std::string &Filename, off_t &StoredSize,
+                                 time_t &StoredTime, bool &Overridden) {
+  // Go find this input file.
+  BitstreamCursor &Cursor = F.InputFilesCursor;
+  SavedStreamPosition SavedPosition(Cursor);
+  Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
+
+  unsigned Code = Cursor.ReadCode();
+  RecordData Record;
+  StringRef Blob;
+
+  unsigned Result = Cursor.readRecord(Code, Record, &Blob);
+  assert(static_cast<InputFileRecordTypes>(Result) == INPUT_FILE &&
+         "invalid record type for input file");
+  (void)Result;
+
+  assert(Record[0] == ID && "Bogus stored ID or offset");
+  StoredSize = static_cast<off_t>(Record[1]);
+  StoredTime = static_cast<time_t>(Record[2]);
+  Overridden = static_cast<bool>(Record[3]);
+  Filename = Blob;
+  MaybeAddSystemRootToFilename(F, Filename);
+}
+
+std::string ASTReader::getInputFileName(ModuleFile &F, unsigned int ID) {
+  off_t StoredSize;
+  time_t StoredTime;
+  bool Overridden;
+  std::string Filename;
+  readInputFileInfo(F, ID, Filename, StoredSize, StoredTime, Overridden);
+  return Filename;
+}
+
 InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
   // If this ID is bogus, just return an empty input file.
   if (ID == 0 || ID > F.InputFilesLoaded.size())
@@ -1820,119 +1914,105 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
   SavedStreamPosition SavedPosition(Cursor);
   Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
   
-  unsigned Code = Cursor.ReadCode();
-  RecordData Record;
-  StringRef Blob;
-  switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) {
-  case INPUT_FILE: {
-    unsigned StoredID = Record[0];
-    assert(ID == StoredID && "Bogus stored ID or offset");
-    (void)StoredID;
-    off_t StoredSize = (off_t)Record[1];
-    time_t StoredTime = (time_t)Record[2];
-    bool Overridden = (bool)Record[3];
-    
-    // Get the file entry for this input file.
-    StringRef OrigFilename = Blob;
-    std::string Filename = OrigFilename;
-    MaybeAddSystemRootToFilename(F, Filename);
-    const FileEntry *File 
-      = Overridden? FileMgr.getVirtualFile(Filename, StoredSize, StoredTime)
-                  : FileMgr.getFile(Filename, /*OpenFile=*/false);
-    
-    // If we didn't find the file, resolve it relative to the
-    // original directory from which this AST file was created.
-    if (File == 0 && !F.OriginalDir.empty() && !CurrentDir.empty() &&
-        F.OriginalDir != CurrentDir) {
-      std::string Resolved = resolveFileRelativeToOriginalDir(Filename,
-                                                              F.OriginalDir,
-                                                              CurrentDir);
-      if (!Resolved.empty())
-        File = FileMgr.getFile(Resolved);
-    }
-    
-    // For an overridden file, create a virtual file with the stored
-    // size/timestamp.
-    if (Overridden && File == 0) {
-      File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);
+  off_t StoredSize;
+  time_t StoredTime;
+  bool Overridden;
+  std::string Filename;
+  readInputFileInfo(F, ID, Filename, StoredSize, StoredTime, Overridden);
+
+  const FileEntry *File
+    = Overridden? FileMgr.getVirtualFile(Filename, StoredSize, StoredTime)
+                : FileMgr.getFile(Filename, /*OpenFile=*/false);
+
+  // If we didn't find the file, resolve it relative to the
+  // original directory from which this AST file was created.
+  if (File == 0 && !F.OriginalDir.empty() && !CurrentDir.empty() &&
+      F.OriginalDir != CurrentDir) {
+    std::string Resolved = resolveFileRelativeToOriginalDir(Filename,
+                                                            F.OriginalDir,
+                                                            CurrentDir);
+    if (!Resolved.empty())
+      File = FileMgr.getFile(Resolved);
+  }
+
+  // For an overridden file, create a virtual file with the stored
+  // size/timestamp.
+  if (Overridden && File == 0) {
+    File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);
+  }
+
+  if (File == 0) {
+    if (Complain) {
+      std::string ErrorStr = "could not find file '";
+      ErrorStr += Filename;
+      ErrorStr += "' referenced by AST file";
+      Error(ErrorStr.c_str());
     }
-    
-    if (File == 0) {
-      if (Complain) {
-        std::string ErrorStr = "could not find file '";
-        ErrorStr += Filename;
-        ErrorStr += "' referenced by AST file";
-        Error(ErrorStr.c_str());
-      }
-      // Record that we didn't find the file.
-      F.InputFilesLoaded[ID-1] = InputFile::getNotFound();
-      return InputFile();
-    }
-
-    // Check if there was a request to override the contents of the file
-    // that was part of the precompiled header. Overridding such a file
-    // can lead to problems when lexing using the source locations from the
-    // PCH.
-    SourceManager &SM = getSourceManager();
-    if (!Overridden && SM.isFileOverridden(File)) {
-      if (Complain)
-        Error(diag::err_fe_pch_file_overridden, Filename);
-      // After emitting the diagnostic, recover by disabling the override so
-      // that the original file will be used.
-      SM.disableFileContentsOverride(File);
-      // The FileEntry is a virtual file entry with the size of the contents
-      // that would override the original contents. Set it to the original's
-      // size/time.
-      FileMgr.modifyFileEntry(const_cast<FileEntry*>(File),
-                              StoredSize, StoredTime);
-    }
-
-    bool IsOutOfDate = false;
-
-    // For an overridden file, there is nothing to validate.
-    if (!Overridden && (StoredSize != File->getSize()
+    // Record that we didn't find the file.
+    F.InputFilesLoaded[ID-1] = InputFile::getNotFound();
+    return InputFile();
+  }
+
+  // Check if there was a request to override the contents of the file
+  // that was part of the precompiled header. Overridding such a file
+  // can lead to problems when lexing using the source locations from the
+  // PCH.
+  SourceManager &SM = getSourceManager();
+  if (!Overridden && SM.isFileOverridden(File)) {
+    if (Complain)
+      Error(diag::err_fe_pch_file_overridden, Filename);
+    // After emitting the diagnostic, recover by disabling the override so
+    // that the original file will be used.
+    SM.disableFileContentsOverride(File);
+    // The FileEntry is a virtual file entry with the size of the contents
+    // that would override the original contents. Set it to the original's
+    // size/time.
+    FileMgr.modifyFileEntry(const_cast<FileEntry*>(File),
+                            StoredSize, StoredTime);
+  }
+
+  bool IsOutOfDate = false;
+
+  // For an overridden file, there is nothing to validate.
+  if (!Overridden && (StoredSize != File->getSize()
 #if !defined(LLVM_ON_WIN32)
-         // In our regression testing, the Windows file system seems to
-         // have inconsistent modification times that sometimes
-         // erroneously trigger this error-handling path.
-         || StoredTime != File->getModificationTime()
+       // In our regression testing, the Windows file system seems to
+       // have inconsistent modification times that sometimes
+       // erroneously trigger this error-handling path.
+       || StoredTime != File->getModificationTime()
 #endif
-         )) {
-      if (Complain) {
-        // Build a list of the PCH imports that got us here (in reverse).
-        SmallVector<ModuleFile *, 4> ImportStack(1, &F);
-        while (ImportStack.back()->ImportedBy.size() > 0)
-          ImportStack.push_back(ImportStack.back()->ImportedBy[0]);
-
-        // The top-level PCH is stale.
-        StringRef TopLevelPCHName(ImportStack.back()->FileName);
-        Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName);
-
-        // Print the import stack.
-        if (ImportStack.size() > 1 && !Diags.isDiagnosticInFlight()) {
+       )) {
+    if (Complain) {
+      // Build a list of the PCH imports that got us here (in reverse).
+      SmallVector<ModuleFile *, 4> ImportStack(1, &F);
+      while (ImportStack.back()->ImportedBy.size() > 0)
+        ImportStack.push_back(ImportStack.back()->ImportedBy[0]);
+
+      // The top-level PCH is stale.
+      StringRef TopLevelPCHName(ImportStack.back()->FileName);
+      Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName);
+
+      // Print the import stack.
+      if (ImportStack.size() > 1 && !Diags.isDiagnosticInFlight()) {
+        Diag(diag::note_pch_required_by)
+          << Filename << ImportStack[0]->FileName;
+        for (unsigned I = 1; I < ImportStack.size(); ++I)
           Diag(diag::note_pch_required_by)
-            << Filename << ImportStack[0]->FileName;
-          for (unsigned I = 1; I < ImportStack.size(); ++I)
-            Diag(diag::note_pch_required_by)
-              << ImportStack[I-1]->FileName << ImportStack[I]->FileName;
-        }
-
-        if (!Diags.isDiagnosticInFlight())
-          Diag(diag::note_pch_rebuild_required) << TopLevelPCHName;
+            << ImportStack[I-1]->FileName << ImportStack[I]->FileName;
       }
 
-      IsOutOfDate = true;
+      if (!Diags.isDiagnosticInFlight())
+        Diag(diag::note_pch_rebuild_required) << TopLevelPCHName;
     }
 
-    InputFile IF = InputFile(File, Overridden, IsOutOfDate);
-
-    // Note that we've loaded this input file.
-    F.InputFilesLoaded[ID-1] = IF;
-    return IF;
-  }
+    IsOutOfDate = true;
   }
 
-  return InputFile();
+  InputFile IF = InputFile(File, Overridden, IsOutOfDate);
+
+  // Note that we've loaded this input file.
+  F.InputFilesLoaded[ID-1] = IF;
+  return IF;
 }
 
 const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) {
@@ -2001,6 +2081,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
       // Validate input files.
       const HeaderSearchOptions &HSOpts =
           PP.getHeaderSearchInfo().getHeaderSearchOpts();
+
       if (!DisableValidation &&
           (!HSOpts.ModulesValidateOncePerBuildSession ||
            F.InputFilesValidationTimestamp <= HSOpts.BuildSessionTimestamp)) {
@@ -2014,17 +2095,25 @@ ASTReader::ReadControlBlock(ModuleFile &F,
         // files.
         unsigned NumInputs = Record[0];
         unsigned NumUserInputs = Record[1];
-        unsigned N = ValidateSystemInputs ||
-                             (HSOpts.ModulesValidateOncePerBuildSession &&
-                              F.Kind == MK_Module)
-                         ? NumInputs
-                         : NumUserInputs;
+        unsigned N = NumUserInputs;
+        if (ValidateSystemInputs ||
+            (HSOpts.ModulesValidateOncePerBuildSession && F.Kind == MK_Module))
+          N = NumInputs;
+
         for (unsigned I = 0; I < N; ++I) {
           InputFile IF = getInputFile(F, I+1, Complain);
           if (!IF.getFile() || IF.isOutOfDate())
             return OutOfDate;
         }
       }
+
+      if (Listener && Listener->needsInputFileVisitation()) {
+        unsigned NumInputs = Record[0];
+        unsigned NumUserInputs = Record[1];
+        for (unsigned I = 0; I < NumInputs; ++I)
+          Listener->visitInputFile(getInputFileName(F, I+1), I >= NumUserInputs);
+      }
+
       return Success;
     }
 
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 3365d1e..c209296 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1300,33 +1300,6 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
       SortedFiles.push_front(Entry);
   }
 
-  // If we have an isysroot for a Darwin SDK, include its SDKSettings.plist in
-  // the set of (non-system) input files. This is simple heuristic for
-  // detecting whether the system headers may have changed, because it is too
-  // expensive to stat() all of the system headers.
-  FileManager &FileMgr = SourceMgr.getFileManager();
-  if (!HSOpts.Sysroot.empty() && !Chain) {
-    llvm::SmallString<128> SDKSettingsFileName(HSOpts.Sysroot);
-    llvm::sys::path::append(SDKSettingsFileName, "SDKSettings.plist");
-    if (const FileEntry *SDKSettingsFile = FileMgr.getFile(SDKSettingsFileName)) {
-      InputFileEntry Entry = { SDKSettingsFile, false, false };
-      SortedFiles.push_front(Entry);
-    }
-  }
-
-  // Add the compiler's own module.map in the set of (non-system) input files.
-  // This is a simple heuristic for detecting whether the compiler's headers
-  // have changed, because we don't want to stat() all of them.
-  if (Modules && !Chain) {
-    SmallString<128> P = StringRef(HSOpts.ResourceDir);
-    llvm::sys::path::append(P, "include");
-    llvm::sys::path::append(P, "module.map");
-    if (const FileEntry *ModuleMapFile = FileMgr.getFile(P)) {
-      InputFileEntry Entry = { ModuleMapFile, false, false };
-      SortedFiles.push_front(Entry);
-    }
-  }
-
   unsigned UserFilesNum = 0;
   // Write out all of the input files.
   std::vector<uint32_t> InputFileOffsets;
@@ -1363,7 +1336,7 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
     
     // Ask the file manager to fixup the relative path for us. This will 
     // honor the working directory.
-    FileMgr.FixupRelativePath(FilePath);
+    SourceMgr.getFileManager().FixupRelativePath(FilePath);
     
     // FIXME: This call to make_absolute shouldn't be necessary, the
     // call to FixupRelativePath should always return an absolute path.
diff --git a/test/Modules/dependency-gen.m b/test/Modules/dependency-gen.m
new file mode 100644
index 0000000..67e590b
--- /dev/null
+++ b/test/Modules/dependency-gen.m
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t-mcp
+// RUN: mkdir -p %t-mcp
+
+// RUN: %clang_cc1 -x objective-c -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -dependency-file %t.d.1 -MT %s.o -I %S/Inputs -fsyntax-only -fmodules -fmodules-cache-path=%t-mcp %s
+// RUN: FileCheck %s < %t.d.1
+// CHECK: dependency-gen.m
+// CHECK: Inputs/diamond_top.h
+// CHECK: Inputs/module.map
+// CHECK-NOT: usr{{.}}include{{.}}module.map
+// CHECK-NOT: stdint.h
+
+
+// RUN: %clang_cc1 -x objective-c -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -dependency-file %t.d.2 -MT %s.o -I %S/Inputs -sys-header-deps -fsyntax-only -fmodules -fmodules-cache-path=%t-mcp %s
+// RUN: FileCheck %s -check-prefix=CHECK-SYS < %t.d.2
+// CHECK-SYS: dependency-gen.m
+// CHECK-SYS: Inputs/diamond_top.h
+// CHECK-SYS: Inputs/module.map
+// CHECK-SYS: usr{{.}}include{{.}}module.map
+// CHECK-SYS: stdint.h
+
+#import "diamond_top.h"
+#import "stdint.h" // inside sysroot
