Introduce the notion of a single "delayed" diagnostic into the
Diagnostic subsystem, which is used in the rare case where we find a
serious problem (i.e., an inconsistency in the file system) while
we're busy formatting another diagnostic. In this case, the delayed
diagnostic will be emitted after we're done with the other
diagnostic. This is only to be used for fatal conditions detected at
very inconvenient times, where we can neither stop the current
diagnostic in flight nor can we suppress the second error.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99175 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index c34f3e2..27cb9be 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -89,15 +89,26 @@
       char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart());
       for (unsigned i = 0, e = Entry->getSize(); i != e; ++i)
         Ptr[i] = FillStr[i % FillStr.size()];
-      Diag.Report(diag::err_cannot_open_file)
-        << Entry->getName() << ErrorStr;
+
+      if (Diag.isDiagnosticInFlight())
+        Diag.SetDelayedDiagnostic(diag::err_cannot_open_file, 
+                                  Entry->getName(), ErrorStr);
+      else 
+        Diag.Report(diag::err_cannot_open_file)
+          << Entry->getName() << ErrorStr;
+
       Buffer.setInt(true);
     } else if (FileInfo.st_size != Entry->getSize() ||
                FileInfo.st_mtime != Entry->getModificationTime()) {
       // Check that the file's size, modification time, and inode are
       // the same as in the file entry (which may have come from a
       // stat cache).
-      Diag.Report(diag::err_file_modified) << Entry->getName();
+      if (Diag.isDiagnosticInFlight())
+        Diag.SetDelayedDiagnostic(diag::err_file_modified, 
+                                  Entry->getName());
+      else 
+        Diag.Report(diag::err_file_modified) << Entry->getName();
+
       Buffer.setInt(true);
     }
   }